Reputation: 27346
I've got an issue involving scheduled tasks and Hibernate. I'm trying to use the java Timer
object to schedule a task to run once a second. That tasks involves querying a database via hibernate. Now, as far as I understand it, Hibernate getCurrentSession()
method will return a session bound to the current context.
Firstly, I am using this code to schedule the task:
timer = new Timer();
task = new UpdateTask();
// Schedule the task for future runs.
timer.scheduleAtFixedRate(task, 1000, 1000);
The code for the task is as follows:
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();
}
}
Finally, here is the code is the DAO
object that is retrieving the information:
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();
}
And the getSession
method is the origin of the NPE, which is as follows:
public Session getSession(){
return sessionFactory.getCurrentSession();
}
The line return sessionFactory.getCurrentSession();
is the origin of the error. Now, this obviously means the sessionFactory
is null. However, in my code, the exact same database request is made in the previous line. This tells me that the sessionFactory
isn't null because the previous request is successful.
Here is a stack trace of the 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)
Just for reference..
meetings = meetingService.getMeetings(date);
// meetingService is the wrapper for the DAO object. this is the successful request.
And this is how I start my request:
us.startTimer();
Which starts off the call chain, with the timer
code at the top.
Edits I've made to try and fix it
So I added in a new bean
tag into the applicationContext.xml
file. That looks like this:
<bean id="updateTask" class="com.sis.rawfilter.domain.UpdateTask"/>
And I've added in the Autowired
tag into the class for the fields:
@Autowired
private IMeetingService meetingService;
@Autowired
private IFilterMeetingService filterMeetingService;
These types are declared in the applicationContext file as:
<bean id="meetingService" class="com.sis.rawfilter.service.impl.MeetingService"/>
<bean id="filterMeetingService" class="com.sis.rawfilter.service.impl.FilterMeetingService"/>
Sample Service Class
@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;
}
}
Sample Dao Class
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);
}
}
}
Upvotes: 0
Views: 1972
Reputation: 4807
You are creating new object of meeting dao
new MeetingDao().getMeetings(date);
so sessionFactory
object will not initialize and obviously you will get nullPointerException
, you should Autowired
dao.
Upvotes: 1