4

I have just started making a project using spring and hibernate. My DAO layer class extends HibernateDaoSupport. We are not using annotations. Earlier, we were using struts, hence we used getTransaction, commit, rollback .. methods provided by Session class. My requirement is very simple, for all DAO classes, if there is an exception, rollback otherwise commit. Please suggest a simplest way of introducing spring transaction management.

saurav
  • 3,424
  • 1
  • 22
  • 33
Sushant Gupta
  • 1,487
  • 2
  • 16
  • 23

1 Answers1

12

A few things are not clear from your question. My explanation follows based on below assumptions -

  • You are using spring to create a datasource and session factory
  • You are using Java 5 or above and could use annotations.

Here is what your spring configuration would look like.

    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
    <property name="url" value="jdbc:hsqldb:hsql://localhost:9001" />
    <property name="username" value="sa" />
    <property name="password" value="" />
</bean>

<bean id="mySessionFactory"
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="myDataSource" />
    <property name="mappingResources">
        <list>
            <value>product.hbm.xml</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <value>
            hibernate.dialect=org.hibernate.dialect.HSQLDialect
        </value>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="mySessionFactory" />
</bean> 

<tx:annotation-driven transaction-manager="transactionManager"  />

Once this is set up, you could use spring transactional annotations on your DAO methods as shown below. Spring would take care of starting transactions, committing your transactions or rolling back your transactions when exceptions are thrown. If you have business services, you would ideally use transactional annotations on your services instead of DAOs.

@Transactional(propagation=Propagation.REQUIRED)
public class MyTestDao extends HibernateDaoSupport {    
public void saveEntity(Entity entity){
    getHibernateTemplate().save(entity);
}
@Transactional(readOnly=true)
public Entity getEntity(Integer id){
    return getHibernateTemplate().get(Entity.class, id);
}
 }

Below code shows how transaction management could be achieve using spring's support for AOP rather than annotations.

    <!-- Define your 'myDatasource' bean and 'mySessionFactory' bean as shown in previous code snippet -->
<!--  Then follow the steps shown below -->

<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory" />   

<!-- this is the dao object that we want to make transactional -->
<bean id="testDao" class="com.xyz.daos.MyTestDao" />

<!-- the transactional advice  -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <!-- all methods starting with 'get' are read-only -->
        <tx:method name="get*" read-only="true" />
        <!-- other methods use the default transaction settings (see below) -->
        <tx:method name="*" propagation="REQUIRED" />
    </tx:attributes>
</tx:advice>

<!-- ensure that the above transactional advice runs for any execution of 
    a method in 'daos' package-->
<aop:config>
    <aop:pointcut id="allDaoMethods"
        expression="execution(* com.xyz.daos.*(..))" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="allDaoMethods" />
</aop:config>

For additional details, please see - Spring Declarative Transactions

Sashi
  • 1,977
  • 16
  • 15
  • Thanks a lot for a clear and precise answer. This example is a quick demo of using annotations. But here I am annotating every method. I need a generic behaviour for all my classes. Is it possible to define this in an xml something like saying.... all my DAO's will follow .....propagation=Propagation.REQUIRED....... without taking help of annotations. – Sushant Gupta Oct 27 '12 at 04:35
  • I guess annotations is the only way ahead. Implemented the same for my requirement. – Sushant Gupta Oct 29 '12 at 10:12
  • You can indeed get the behavior you need using Spring aop. If you decide to go with annotations, a thing to note is that you don't have to annotate each of your methods. You could just annotate your class and all methods inherit that behavior and you could annotate a method to override the behavior. – Sashi Oct 29 '12 at 14:11