Hibernate and Spring DataSourceTransactionManager

I have been trying to work with Hibernate and Spring DataSourceTransactionManager to handle commit and rollback functionality, but I probably am not getting anything.

Before using Spring DataSourceTransactionManager this was one of my DAO classes

  package com.springgestioneerrori.DAO;

  public class UtenteDAO extends DAOBase{   

       public void salvaUtente(Utente utenteIn) throws DAOException{ 

            Session session = getHibernateSession(); //from this method  I get Hibernate SessionFactory
              try{   
                  session.beginTransaction();             
                  session.saveOrUpdate(Object); 
                  session.getTransaction().commit();    
                  }
              catch(Exception e){
                  session.getTransaction().rollback()
              }
        }
}

      

This is the class that sessionFactory gives me

 private static final SessionFactory sessionFactory = buildSessionFactory();

            private static SessionFactory buildSessionFactory() {
                try {
                    // Create the SessionFactory from hibernate.cfg.xml
                    return new AnnotationConfiguration().configure().buildSessionFactory();  
                }
                catch (Throwable ex) {
                              System.err.println("Initial SessionFactory creation failed." + ex);
                    throw new ExceptionInInitializerError(ex);
                }
            }

            public static SessionFactory getSessionFactory() {
                return sessionFactory;
            }

            public static void shutdown() {             
                getSessionFactory().close();
            }

public Session getHibernateSession (){
    Session session = HibernateUtil.getSessionFactory().openSession();
    return session;
}   

      

Now I am trying to use DataSourceTransactionManager in a declarative way. Following some examples on the internet, I wrote the following:

                                

 <tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager" />        

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="salvaUtente"/>
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="userDaoTxPointcut" expression="execution(* com.springgestioneerrori.DAO.UtenteDAO.salvaUtente(..))" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="userDaoTxPointcut" />
</aop:config>       

      

Now, what should I write inside the salvaUtente () method to perform many insertions such as

  session.saveOrUpdate(User); 
  session.saveOrUpdate(UserCredentials); 
  session.saveOrUpdate(UserOtherDetails); 

      

and do Spring notation and descriptor rollback?

+3


source to share


2 answers


First you are using the wrong transaction manager. DataSourceTransactionManager

not for hibernate but for plain JDBC. If you are using plain Hibernate use HibernateTransactionManager

. (Let's assume you are using Hibernate 4 here!).

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

      

Now I propose to use @Transactional

instead of the block <tx:advice />

and <aop:config />

. Makes your configuration easier. Just remove the 2 blocks mentioned and replace them with <tx:annotation-driven />

.

<tx:annotation-driven />

      

Now your code is wrong when you start transactions yourself. Annotate your method with @Transactional

(after adding above) and remove the transaction handling code.

@Transactional
public void salvaUtente(Utente utenteIn) throws DAOException{ 
    Session session = getHibernateSession(); //from this method  I get Hibernate SessionFactory
    session.saveOrUpdate(Object); 
}

      

Now I don't know what your method does getHibenateSession

, but make sure you don't use openSession

in SessionFactory

to get the session. Use instead getCurrentSession

.



protected Session getHibernateSession() {
    return sessionFactory.getCurrentSession();
}

      

Your current class BaseDAO

is wrong. Uninstall buildSessionFactory

and uninstall static final

. Let Spring configure and enter SessionFactory

.

public abstract class BaseDAO {

    @Autowired
    private SessionFactory sessionFactory;

    protected Session getHibernateSession() {
        return sessionFactory.getCurrentSession();
    }
}

      

In your config add the config for LocalSessionFactoryBean

.

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    ... Other Hibernate Properties
</bean>

      

This is basically all it takes. This is also detailed in the Spring reference manual . I highly recommend reading.

+4


source


I would suggest

@Transaction(rollbackFor = {if you need to rollback on certain checked exception})
salvaUtente()

      



The transaction is executed only for an unchecked exception, unless otherwise noted.

if there is any exception at any point in the salvaUtente in the transaction it will be rolled back, otherwise the transaction will be committed after the method exists

0


source







All Articles