Hi everybody,
I use Hibernate 3 + Spring (with regular hbm mapping files - no JPA annotation) in a layered application.
Service layer transactions are declarative (with annotations) managed by org.springframework.orm.hibernate3.HibernateTransactionManager.
In one of these services a transaction is opened declaratively :
Code:
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = { AbstractApplicationException.class })
public void updateAll(FormVO form) throws FunctionalException, TechnicalException
...
The DAO is then called which in turn opens or join the current transaction :
Code:
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public int update(int documentIndex, Map< String, ? > fieldsValues) throws DAOException
The DAO executes a query :
Code:
...
hqlQuery.executeUpdate();
...
It seems that this query is immediately flushed, because I can see it in the log (I have checked the flusmode, it is AUTO):
Code:
15:32:04,272 INFO [STDOUT] Hibernate: update idx set H_AMOUNT=?, H_CUSTOM2=?, H_CURRENCYEXCHRATE=?, H_TAXRATE=?, H_CURRENCY=?, H_CONFORMSTA=?, H_CHARGAMT=?, H_TAXAMT=?, H_CUSTOM3=?, H_PAYMTMODE=?, H_INVOICTYPE=?, SUPPLIERNAME=?, H_INVOICNBR=?, H_INVOICDATE=?, H_SUPPLIERID=?, STATUS=?, H_RECDATE=?, H_TOTAMT=?, H_INVOICECAT=?, H_CUSTOM1=?, H_DISCOAMT=?, H_INVOICCONFID=?, H_DUEDATE=? where DOCIDX=?
The DAO method then returns and execution carry on in the service layer.
The problem is that if an exception occurs in the service, the update is not rolled-back since the DAO method execution is over.
In some other service, when a DAO is called, getSession().merge() is executed instead. And it doesn't cause any immediate flush.
How to prevent this to occur ?
How to make the DAO code rolled-back along with the other service layer operations ?
Best regards,
Eric