Nested Transactions and propogation_required
I have a message driven bean which calls a save method on a DAO class. I have the DAO save method declaratively wrapped in a Propogation_required transaction. The transaction manager managing this transaction is the HibernateTransactionManager. The message driven bean calling the DAO is within a jboss container managed transaction. When the MDB calls the DAO I get an exception. It seems as if there is a problem having a JDBC transaction nested within a container managed transaction. The behaviour i am looking for is that the DAO simply participates in the Message Driven Bean transaction. I'll paste some of the exception below. Thanks.
Karl
Caused by: java.sql.SQLException: You cannot commit during a managed transaction!
at org.jboss.resource.adapter.jdbc.BaseWrapperManaged Connection.jdbcCommit()V(BaseWrapperManagedConnect ion.java:
525)
at org.jboss.resource.adapter.jdbc.WrappedConnection. commit()V(WrappedConnection.java:464)
at net.sf.hibernate.transaction.JDBCTransaction.commi t()V(JDBCTransaction.java:63)
at org.springframework.orm.hibernate.HibernateTransac tionManager.doCommit(Lorg.springframework.transact ion.suppo
rt.DefaultTransactionStatus;)V(HibernateTransactio nManager.java:386)
at org.springframework.transaction.support.AbstractPl atformTransactionManager.commit(Lorg.springframewo rk.transa
ction.TransactionStatus;)V(AbstractPlatformTransac tionManager.java:376)
at org.springframework.transaction.interceptor.Transa ctionAspectSupport.doCommitTransactionAfterReturni ng(Lorg.s
pringframework.transaction.interceptor.Transaction AspectSupport$TransactionInfo;)V(TransactionAspect Support.java:278)
at org.springframework.transaction.interceptor.Transa ctionInterceptor.invoke(Lorg.aopalliance.intercept .MethodIn
vocation;)Ljava.lang.Object;(TransactionIntercepto r.java:67)
at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed()Ljava.lang.Object;(ReflectiveM ethodInvo
cation.java:140)
Hibernate, OpenSessionInViewFilter, J2EE transaction manager
To add to my previous response, I have been stepping through the getSession method of SessionFactoryUtils. It seems to me that when using a J2EE transaction manager, the open session is only found when a transaction status is active. Otherwise, a new session will always be opened and closed and you will get lazy initialization exceptions, which I am currently experiencing.
Let me know if I am misunderstanding this method. Thanks again for your help!
Karl
Hibernate, OpenSessionInViewFilter, J2EE transaction manager
Hi Colin. Thanks for the response. To clarify I am using single session mode for my Open Session Filter. I actually stepped through the code through the eclipse remote debugger and saw that it was indeed hitting the following logic in OpenSessionInViewFilter:
Code:
if (isSingleSession()) {
logger.debug("Opening single Hibernate session in OpenSessionInViewFilter");
session = getSession(sessionFactory);
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
}
I think the problem is occuring in this else block in SessionFactoryUtils:
Code:
else {
TransactionManager jtaTm = getJtaTransactionManager(sessionFactory, sessionHolder.getAnySession());
if (jtaTm != null) {
try {
int jtaStatus = jtaTm.getStatus();
if (jtaStatus == Status.STATUS_ACTIVE || jtaStatus == Status.STATUS_MARKED_ROLLBACK) {
Session session = sessionHolder.getSession(jtaTm.getTransaction());
if (session != null) {
return session;
}
}
} catch (SystemException ex) {
throw new DataAccessResourceFailureException("Could not check JTA transaction", ex);
}
} else {
return sessionHolder.getSession();
}
}
When I step through the code, it finds the jta Transaction Manager and checks the jts status. The jta status comes back inactive and the open session is not returned. After exiting out of the else block, the rest of the method seems to be concerned with creating a new session which will eventually cause my application to throw LazyInitialization exceptions as this session will be closed before rendering the view. It seems to me like the session will only be returned if a Transaction is active.
I believe I have traced it down to the specific problem area but I am not sure how to fix this without modifying the spring code. Thanks again for your help.
Karl