I've searched around for this question, there's quite a few of them here on StackOverflow and Google but I can't seem to get anything working for me.
here are my codes Spring config: (I dont use any pointcut - I think I dont need to?)
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
...
</bean>
<bean id="hibernateSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
...
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="hibernateSessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
I have a Service class:
@Service
public class ServiceImpl implements ServiceInterface
{
/**
* Injected session factory
*/
@Autowired(required=true)
private SessionFactory sessionFactory;
@Autowired(required=true)
private Dao myDao;
/**
* {@inheritDoc}
*/
@Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRED)
public void scheduleBlast(BlastParameters blastParameters) throws ServiceException
{
... do bunch of stuff ..
myDao.persist(entity)
if(true)
throw new ServiceException("random error")
}
.. setter methods and other stuff ..
}
and a Dao class:
public class DaoImpl implements DaoInterface
{
@Autowired(required=true)
private SessionFactory sessionFactory
/**
* {@inheritDoc}
*/
@Transactional(propagation=Propagation.MANDATORY)
public void persist(Entity e) throws DaoException
{
try
{
sessionFactory.getCurrentSession().persist(e);
}
catch(Exception ex)
{
throw new DaoException(ex);
}
}
.. setter methods and other stuff ..
}
Some unnecessary details are eliminated (eg. missing setter, etc), assume that code works perfectly fine.
My problem with the above is that when I added the throw random exception line, it does not rollback, the object being persisted through the DAO stays in the db.
I am using Spring 3.1 and Hibernate 3.6 (because there was a bug with Hibernate 4.0 on Spring 3.1)
Thoughts?
Thank you
I found the cause of my problem and why the transaction (seemingly) not managed properly.
Somewhere in my code
/**
* {@inheritDoc}
*/
@Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRED)
public void doWork(Parameters param) throws ServiceException
{
... do bunch of stuff ..
myDao1.persist(entity)
-- Some logic here --
... do bunch of stuff ..
myDao2.persist(entity2)
if(true)
throw new ServiceException("random error")
}
The part where it says "-- Some logic here --", there was some logic done that uses raw SQL and call on execute update:
Query query = sessionFactory.getCurrentSession().createSQLQuery(queryText);
query.executeUpdate();
And because it's not using Hibernate query, and instead using raw SQL execution, it caused a flush to be called and thus any work done prior to the call will be committed along with it.
I re-work the flow of logic to account for this logic to make sure transaction is managed properly. While using raw SQL might be an indication that there's something wrong - it was something necessary to be done due to the things that the service try to accomplish and to improve the performance of the service.