多线程Hibernate会话

时间:2013-08-22 08:40:12

标签: multithreading hibernate

我遇到了涉及计划任务和Hibernate的问题。我正在尝试使用java Timer对象来安排任务每秒运行一次。这些任务涉及通过hibernate查询数据库。现在,据我所知,Hibernate getCurrentSession()方法将返回绑定到当前上下文的会话。

首先,我使用此代码来安排任务:

  timer = new Timer();
  task = new UpdateTask();
  // Schedule the task for future runs.
  timer.scheduleAtFixedRate(task, 1000, 1000);

任务的代码如下:

 public void run() {
    FilterMeetingDao fmService = new FilterMeetingDao();
    Set<String> codes = new HashSet<String>();

    String date = new SimpleDateFormat(Constants.DATE_FORMAT).format(new Date());
    try {
        List<Meeting> meetings = new MeetingDao().getMeetings(date);

        for(Meeting m : meetings)
        {
             if(RawMeetingFilter.isDefaultMeeting(m)) {
                  // Is a default meeting. Insert into the database.
                  codes.add(m.getCode());
             }
        }
        fmService.add(codes, date);
    } catch (ParseException e) {
        e.printStackTrace();
    }
}

最后,代码是正在检索信息的DAO对象:

public List<Meeting> getMeetings(String date) throws ParseException{                        
    SimpleDateFormat sdf = new SimpleDateFormat(Constants.DATE_FORMAT);         
    Date startDate = sdf.parse(date);

    Query query = getSession().createQuery("from Meeting m where m.startDate = :startDate and source not like 'TTV' order by countrycode, categorycode, description");
    query.setParameter("startDate", startDate);     
    return query.list();
}

getSession方法是NPE的起源,如下:

public Session getSession(){
    return sessionFactory.getCurrentSession();
}

return sessionFactory.getCurrentSession();是错误的来源。现在,这显然意味着sessionFactory为空。但是,在我的代码中,确切的相同的数据库请求是在上一行中进行的。这告诉我sessionFactory不为空,因为前一个请求成功。

以下是NullPointerException

的堆栈跟踪
Exception in thread "Timer-0" java.lang.NullPointerException
at com.sis.rawfilter.dao.impl.BaseDao.getSession(BaseDao.java:13)
at com.sis.rawfilter.dao.impl.MeetingDao.getMeetings(MeetingDao.java:21)
at com.sis.rawfilter.domain.UpdateTask.run(UpdateTask.java:32)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)

仅供参考..

meetings = meetingService.getMeetings(date);
// meetingService is the wrapper for the DAO object. this is the successful request.

这就是我开始提出请求的方式:

 us.startTimer();

从调用链开始,顶部有timer代码。

我尝试修改它的编辑

因此,我在bean文件中添加了一个新的applicationContext.xml标记。看起来像这样:

 <bean id="updateTask" class="com.sis.rawfilter.domain.UpdateTask"/>

我已将Autowired标记添加到字段的类中:

@Autowired
private IMeetingService meetingService;

@Autowired
private IFilterMeetingService filterMeetingService;

这些类型在applicationContext文件中声明为:

<bean id="meetingService" class="com.sis.rawfilter.service.impl.MeetingService"/>
<bean id="filterMeetingService" class="com.sis.rawfilter.service.impl.FilterMeetingService"/>

样本服务类

@Transactional
public class FilterMeetingService implements IFilterMeetingService {

@Autowired
private IFilterMeetingDao filterMeetingDao;

public List<FilterMeeting> getFilterMeetings(String date) throws ParseException{
    return filterMeetingDao.getFilterMeetings(date);
}

public void save(Set<String> selectedMeetings, Set<String> excludedMeetings, String date) throws ParseException{    

    if(excludedMeetings.size() > 0){
        filterMeetingDao.remove(excludedMeetings, date);
    }

    if(selectedMeetings.size() > 0){
        filterMeetingDao.add(selectedMeetings, date);
    }
}

public void setFilterMeetingDao(IFilterMeetingDao filterMeetingDao) {
    this.filterMeetingDao = filterMeetingDao;
}

}

样本Dao类

public class FilterMeetingDao extends BaseDao implements IFilterMeetingDao {

@SuppressWarnings("unchecked")
public List<FilterMeeting> getFilterMeetings(String date) throws ParseException{    

    SimpleDateFormat sdf = new SimpleDateFormat(Constants.DATE_FORMAT);         
    Date startDate = sdf.parse(date);

    Query query = getSession().createQuery("from FilterMeeting fm where fm.startDate = :startDate");
    query.setParameter("startDate", startDate);

    return query.list();        
}


public void remove(Set<String> codes, String date){

    Query query = getSession().createSQLQuery("delete from tbl where d = :date and c in :codes ");
    query.setParameter("date", date);
    query.setParameterList("codes", codes);
    query.executeUpdate();
}

public void add(Set<String> codes, String date) throws ParseException{
    SimpleDateFormat sdf = new SimpleDateFormat(Constants.DATE_FORMAT); 

    for(String code : codes){
        FilterMeeting filterMeeting = new FilterMeeting(code,   sdf.parse(date), Config.getInstance().getQueue());
        getSession().save(filterMeeting);   
    }
}

}

1 个答案:

答案 0 :(得分:1)

您正在创建会议dao的新对象

new MeetingDao().getMeetings(date);

所以sessionFactory对象不会初始化,显然你会得到nullPointerException,你应该Autowired dao。