Jan 4, 2014

Get rid of Property 'sessionFactory' is required for Hibernate 4

While using Hibernate 4 with Spring I was down with following error if I tried to use HibernateTemplate or HibernateDAOSupport.
Caused by: java.lang.IllegalArgumentException: Property 'sessionFactory' is required
       at org.springframework.orm.hibernate3.HibernateAccessor.afterPropertiesSet(HibernateAccessor.java:316)
       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
       ... 12 more

This error is comes because of following part in HiberanteTemplate class.
public void afterPropertiesSet() {
       if (getSessionFactory() == null) {
              throw new IllegalArgumentException("Property 'sessionFactory' is required");                   
       }            
}

It was easy to directly use sessionFactory instead of HibernateTemplate or HibernateDAOSupport (and one more rational for doing it was…both these classes are part of hibernte3 package in Spring so who knows down the line they will discontinue the same). But still I tried one tweak and that worked J. I am using example of HiberanteTemplate but same can be done with HibernateDAOSupport. So following are steps.
Ø  Create a class that will extend HibernateTemplate and have local variable for SessionFactory and autowire the same with SessionFactory configured in spring configuration file.
Ø  Override its afterProperties set method where you will set SessionFactory of parent class (i.e. of org.springframework.orm.hibernate3.HibernateTemplate) and then call same method of parent class so nothing is broken.
So following will be our custom HibernateTemplate class.
package com.techcielo.spring4.hibernate.template;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Component;

@Component("hibernateTemplate")
public class Hibernate4CustomTemplate extends HibernateTemplate{
      
       @Autowired(required=true)
       private SessionFactory sessionFactory;
       public void setSessionFactory(SessionFactory sessionFactory) {
              System.out.println("Setting SessionFactory");
              this.sessionFactory = sessionFactory;
              super.setSessionFactory(sessionFactory);
       }
       @Override
       public void afterPropertiesSet() {
              System.out.println("Checking if properties set..."+this.sessionFactory);
              setSessionFactory(sessionFactory);
              super.afterPropertiesSet();
       }
}

One this configuration is done you can configure this in your DAO and you are good. J