Apr 23, 2010

Spring Integration with Hibernate

I was working on a nice web application that was using Spring, Hibernate, jquery and Apache velocity! The saddest fact was the reality that Spring was not properly integrated into Hibernate and transactions were not properly handled.

At last, after a detailed discussion on what would happen if such an application goes live, the spring has been integrated properly with Hibernate! As soon as one starts integrating Hibernate with Spring, the various options would be
  1. To use HibernateTemplate
  2. To use HibernateDaoSupport
  3. Use plain Hibernate with hibernate.cfg.xml (like what we have been using till date)
  4. Autowire session factory as a bean in the daos
The Pros and Cons
  1. Using HibernateTemplate
  2. HibernateTemplate is a nice API from Spring for easy integration with hibernate. It mirrors all methods exposed to Hibernate session and proves to be handy! Automatic session close and transaction participation proves to be the best part of this API. Additionally this is handy not only for the nice exception translation but also helps a newbie who does not want to handle sessions or transactions by himself. But, with the advent of Hibernate 3.0.1, this API (using HibernateTemplate.find and the like  - This includes defining private HibernateTemplate in the daos and setting the hibernate template while setting the session factory in a setter method say setSessionFactory) just proves to be futile and it is highly recommended that it is better to handle the sessionFactory by ourselves rather than clinging to Spring and depending on it for handling the sessions for us! As such, this proves to be the first level of Spring and Hibernate integration and is a good option for a newbie!
  3. Using HibernateDaoSupport
  4. The process of writing SampleDaoImpl extends HibernateDaoSupport is not doubt a very good option. Here, we would then be using no callbacks and session  = getSession(false) rather than setting the hibernate template via the session factory. This is emphatically a very remarkable API provided by Spring for integration with hibernate and is surely better than the option 1 discussed above since this allows throwing of checked exception within the data access code.
  5. Using plain Hibernate with hibernate.cfg.xml
  6. While this proves to be the mos traditional way of implementation, this is just for the hibernate fans. I am not for such an implementation since there is no need for writing code as given below:
    Session session = HibernateUtils.getSession();
    try{
    Transaction tx = session.beginTransaction();
    session.save(Object o);//o is the incoming object to be persisted
    tx.commit();
    }
    catch{
    (Exception e)
    //code to handle exception
    }
    finally{
    session.close();
    
    
  7. Using Autowiring of the SessionFactory
  8. As far as i see, this is the best way of integrating spring with hibernate. This is not only the latest and the updated way of integration, this proves to be the best solution for designing web application where the developer has a hold on the sessions and transactions though Spring does this in its own way
    <br /><br /><?xml version="1.0" encoding="utf-8"?><br /><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"<br />xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"<br />xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"><br /><br /><!-- Auto-detection of the DAOs --><br />    <context:component-scan base-package="webapp.dao" /><br />    <context:property-placeholder location="WEB-INF/jdbc.properties" /><br /><!--<context:property-override location="WEB-INF/override.properties"/>--><br />    <br />    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}"<br />    p:username="${jdbc.username}" p:password="${jdbc.password}" p:maxActive="${dbcp.maxActive}" p:maxIdle="${dbcp.maxIdle}" p:maxWait="${dbcp.maxWait}" /><br />    <br />    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" p:dataSource-ref="dataSource"<br />    p:configurationClass="org.hibernate.cfg.AnnotationConfiguration" p:packagesToScan="webapp.model"><br />        <property name="hibernateProperties"><br />            <props><br />                <prop key="hibernate.dialect">${hibernate.dialect}</prop><br />                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop><br />                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop><br />                <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop><br />            </props><br />        </property><br />       <br />    </bean><br />    <br /> <tx:annotation-driven transaction-manager="txnManager"/> <br /> <bean id="txnManager"<br />        class="org.springframework.orm.hibernate3.HibernateTransactionManager"<br />        p:sessionFactory-ref="sessionFactory"/><br /><br /></beans><br />
    The corresponding DAO class is as below
    @Repository<br />@Transactional<br />public class SampleDaoImpl implements SampleDao {<br /><br />  @Autowired<br />  SessionFactory sessionFactory;<br />

If you find the information pretty helpful, I would really be happy if you would keep me posted via the comments form displayed under this article! If you had wanted some other information related to the same topic, I would suggest you to drop a note to me using the comments form for that would help me in getting back to you with the details you are in need of!

6 comments:

  1. Good article. Just wish it had been written longer and with many details.

    But any way, what are the Jar Files needed for Spring Hibernate Integration? And where to download, if any?

    ReplyDelete
  2. More details needed:

    What are your:

    webapp.dao
    jdbc.properties

    ReplyDelete
  3. @Anonymous,

    Let me tell you that the list of jars would entirely depend on the requirements of your current project. But for the kick off, try having the following jars for the integration. The list is based on the assumption that you are using TxManager, @Value annnotations, Spring 3.0, hibernate annotations, spring transactions etc. Just keep us all posted as to how you are progressing with the below list and if you need help, please do let us know too!

    com.springsource.org.aopalliance-1.0.0.jar
    org.springframework.beans-3.0.0.RELEASE.jar
    org.springframework.context.support-3.0.0.RELEASE.jar
    org.springframework.context-3.0.0.RELEASE.jar
    org.springframework.core-3.0.0.RELEASE.jar
    org.springframework.expression-3.0.0.RELEASE.jar
    org.springframework.jdbc-3.0.0.RELEASE.jar
    org.springframework.orm-3.0.0.RELEASE.jar
    org.springframework.transaction-3.0.0.RELEASE.jar
    org.springframework.web.servlet-3.0.0.RELEASE.jar
    org.springframework.web-3.0.0.RELEASE.jar

    hibernate3.jar
    hibernate-annotations.jar
    hibernate-commons-annotations.jar
    hibernate-entitymanager.jar

    ReplyDelete
  4. @Anonymous,

    Coming to your question on the content of jdbc.properties, here are the details,

    jdbc.driverClassName=
    jdbc.url=
    jdbc.username=
    jdbc.password=

    dbcp.maxActive=100 (sample given here)
    dbcp.maxIdle=30(sample given here)
    dbcp.maxWait=16000(sample given here)

    hibernate.generate_statistics=true(sample given here)
    hibernate.show_sql=true(sample given here)
    hibernate.format_sql=false(sample given here)
    hibernate.dialect=


    and coming to the daoimpl class, you would have to have the above given code and within your dao methods, access the session using

    sessionFactory.getCurrentSession().createQuery("").list(); or
    sessionFactory.getCurrentSession().delete(Obj);

    Exceptions need not be caught since spring takes care of it.

    ReplyDelete
  5. I find this article very useful, It would be nice if you have some sample code for all the 4 methods.

    Thanks

    ReplyDelete
  6. @anonymous
    Could you let me know for which you would require a detailed sample or which are the methods for which you need working samples? Let me know

    ReplyDelete