Quartz, Spring & Hibernate/JPA

Establishing a hibernate session in a wicket application is done by means of the OpenSessionInViewFilter class, which binds a Hibernate Session to the thread for the entire processing of the request. You’ll find plenty of references by googling for Wicket and Hibernate.

If you need background jobs to be executed, Quartz is a fantastic library, providing scheduling with cron syntax. Quartz is trivial to integrate into your application (whether with Spring or without), but we had a hard time to figure out how to handle Hibernate sessions correctly. When you want to use one of your DAOs in a Quartz Job you are very likely to hit a “Session is closed!” exception from Hibernate. The reason for this is that the Quartz Job does not run within the context of the servlet, therefore nobody took care of establishing a Hibernate Session.

Below you’ll find a sample Quartz Job which shows how to set up the Hibernate session like OpenSessionInViewFilter does during a servlet request:

package sample;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.jpa.EntityManagerHolder;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.transaction.support.TransactionSynchronizationManager;

public class SampleJobBean extends QuartzJobBean {

  @Override
  protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
    EntityManagerFactory emf = null;
    EntityManager em = null;
    try {
      ApplicationContext appContext = (ApplicationContext) jobExecutionContext.getScheduler().getContext().get("applicationContext");
      EntityManagerFactory emf = (EntityManagerFactory) appContext.getBean("entityManagerFactory", EntityManagerFactory.class);
      em = emf.createEntityManager();
      TransactionSynchronizationManager.bindResource(emf, new EntityManagerHolder(em));

      /* Some action */

    } catch (Exception e) {
      //Exception handling..
      e.printStackTrace();
    }
    finally{
      if (em!=null) em.close();
    }
  }
}

Below you’ll find the relevant sections from the corresponding applicationContext.xml file.



  
    
  


  
    
  



  
    
      
    
  
  
    applicationContext
  




  

Thanks to Uwe Schäfer who helped us find this solution!