Tuesday, November 5, 2013

Upgrade from Hibernate to Spring with HibernateDaoSupport

There is a program has already implementing Hibernate as its natural implementation when retrieving data from database. At the very first glance on the code, it’s very clean. Code snippet below is the main function of the program, this function hold an instance of BookDao.
 public static void main(String args[]) {

  BookDao bookDao = new BookDao();
  
  List< book > bookList = bookDao.readAll();
  
  if( bookList == null ) {
   System.out.println("No book records found");
  }
 }
The BookDao has a readAll() that retrieve the data from database and return the book list back to the main function.
public class BookDao {
 public List< book > readAll() {
  
  List< book > bookList = null;
  Session session = SessionManager.getSessionFactory().getCurrentSession();
  session.beginTransaction();
  bookList = session.createQuery("from Book").list();

  return bookList;
 }
 ...
 ...
}
This is the Hibernate mapping of the book entity. It is pretty straight forward.

 
  
   
  
  
  
  
  
 

Well, not much nonsense in this program. In one day, there is a requirement to integrate this DAO with Spring framework. Things start to get complicated, in the same time more code to write.

Step 1 – I need to have a data source bean configure in Spring. Pump in all the required information into this bean to bridge my program and my desire database, in my case is MYSQL.
 
  
  
  
  
 
Step 2 – I need to have a sessionFactory bean configure in Spring because the DAO will need this bean to initialize the session in Spring. Port over the data source declares in Step 1 to tell which connection that this session will hold.
 
  
   
  
  
  
   
    org.hibernate.dialect.MySQLInnoDBDialect
    org.hibernate.hql.ast.ASTQueryTranslatorFactory
    100
    false
    auto
    thread
    false
    false
    true
    true
   
  
  
  
   
    Book.hbm.xml
   
  
 
Step 3 - Revamp BookDao to extends HibernateDaoSupport. Note on the remark at (1), the session is came from the sessionFactory declare in step 2. Also take note that I’m no longer call beginTransaction() in order to execute the query.
public class BookDao extends HibernateDaoSupport {
 
 public List< Book > readAll() {
  List< Book > bookList = null;
  Session session = getSession();    // (1)
  bookList = session.createQuery("from org.huahsin.Book").list();
  
  return bookList;
 }
 ...
 ...
}
Step 4 – Inject the sessionFactory bean into DAO. This is to tell DAO which session and connection will be use to communicate to database.
 
  
 
Take note that if the sessionFactory is not injects into DAO in this step, when this BookDao bean is first load. Following error would be seen immediately.
Caused by: java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required
 at org.springframework.orm.hibernate3.support.HibernateDaoSupport.checkDaoConfig(HibernateDaoSupport.java:118)
 at org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1479)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1419)
 ... 12 more
Last but not least, the hibernate.cfg.xml may throw away since it is not needed anymore. This is all about the work need to be done when migrate to Spring’s HibernateDaoSupport.

No comments: