Reputation: 4267
I'm trying to work with Hibernate and Spring DataSourceTransactionManager to handle commit and rollback functions, but probably I dind't get something.
Before using Spring DataSourceTransactionManager, this was one of my DAO class
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 give me the sessionFactory
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'm trying to use DataSourceTransactionManager in a declarative way. Following some examples on the internet I wrote this:
<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 method salvaUtente() to perform many inserts, for example like these
session.saveOrUpdate(User);
session.saveOrUpdate(UserCredentials);
session.saveOrUpdate(UserOtherDetails);
and making Spring handle commint and rollback?
Upvotes: 5
Views: 4874
Reputation: 441
HibernateTransactionManager can also manage the transactions on the DataSource. We need to inject the DataSource in the HibernateTransactionManager and it should work for both, Hibernate and plain old SQL.
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager>
<property name="sessionFactory" ref="sessionFactory"/>
<property name="dataSource" ref="dataSource"/>
</bean>
Hope this works for you.
(I know this is pretty late, but may help someone landing to this post)
Upvotes: 0
Reputation: 124909
First you are using the wrong transaction manager. The DataSourceTransactionManager
isn't for Hibernate but for plain JDBC. If you are using plain Hibernate use the HibernateTransactionManager
. (Assuming that you are using Hibernate 4 here!).
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Now I would also suggest to use @Transactional
instead of a <tx:advice />
and <aop:config />
block. Makes your configuration easier. Simply remove the 2 mentioned blocks and replace with <tx:annotation-driven />
.
<tx:annotation-driven />
Now your code is wrong as you are starting transactions yourself. Annotate your method with @Transactional
(after adding the thing above) and remove your 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 getHibenateSession
method does but make sure you don't use openSession
on the SessionFactory
to obtain a session. Use getCurrentSession
instead.
protected Session getHibernateSession() {
return sessionFactory.getCurrentSession();
}
Your current BaseDAO
class is flawed. Delete your buildSessionFactory
and remove the static final
. Let Spring configure and inject the SessionFactory
.
public abstract class BaseDAO {
@Autowired
private SessionFactory sessionFactory;
protected Session getHibernateSession() {
return sessionFactory.getCurrentSession();
}
}
In your configuration add the configuration for the LocalSessionFactoryBean
.
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
... Other Hibernate Properties
</bean>
That is basically all that is needed. This is also all explained in detail in the Spring Reference guide. I strongly suggest a read.
Upvotes: 5
Reputation: 184
I would suggest
@Transaction(rollbackFor = {if you need to rollback on certain checked exception})
salvaUtente()
The transaction is only roll backed for unchecked exception until mentioned otherwise.
if there is an exception at any point salvaUtente in the transaction will be roll backed else the transaction will be committed once the method is existed
Upvotes: 0