我遇到了一个涉及计划任务和休眠的问题。我正在尝试使用 javaTimer
对象来安排任务每秒运行一次。该任务涉及通过休眠查询数据库。现在,据我了解,HibernategetCurrentSession()
方法将返回一个绑定到当前上下文的会话。
首先,我使用此代码来安排任务:
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
is null。但是,在我的代码中,在前一行中发出了完全相同的数据库请求。这告诉我sessionFactory
不是 null,因为之前的请求是成功的。
这是一个堆栈跟踪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;
}
}
示例道类
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);
}
}
}