Interceptor.afterTransactionCompletion not called with JTATransaction (CacheSynchronization.hibernateTransaction not set)

Description

interceptor.afterTransactionCompletion should be invoked in SessionImpl.afterTransactionCompletion, but it is only called if the tx parameter is not null. When running under a JTA environment, that parameter will always be null. This is the stack which leads to the call (line numbers are from v3.1.2 code):

org.hibernate.impl.SessionImpl.afterTransactionCompletion(boolean, org.hibernate.Transaction) line: 442
org.hibernate.jdbc.JDBCContext.afterTransactionCompletion(boolean, org.hibernate.Transaction) line: 205
org.hibernate.transaction.CacheSynchronization.afterCompletion(int) line: 85
org.jboss.tm.TransactionImpl.doAfterCompletion() line: 1508
org.jboss.tm.TransactionImpl.completeTransaction() line: 1180
org.jboss.tm.TransactionImpl.commit() line: 359
org.jboss.tm.TxManager.commit() line: 224
org.jboss.tm.usertx.client.ServerVMClientUserTransaction.commit() line: 126
org.hibernate.transaction.JTATransaction.commit() line: 146

The problem is that the hibernateTransaction member variable of the CacheSynchronization object is never set. Here is the call stack for how that object is created:

org.hibernate.transaction.CacheSynchronization.<init>(org.hibernate.transaction.TransactionFactory$Context, org.hibernate.jdbc.JDBCContext, javax.transaction.Transaction, org.hibernate.Transaction) line: 34
org.hibernate.jdbc.JDBCContext.registerSynchronizationIfPossible() line: 149
org.hibernate.transaction.JTATransaction.begin() line: 102
org.hibernate.impl.SessionImpl.beginTransaction() line: 1309
com.osc.util.hibernate.HibernateManager.getSession(org.hibernate.Interceptor) line: 204

You can see in the JDBCContext.registerSynchronizationIfPossible() method that the parameter to set the transaction is always null, even though the JDBCContext object does have a reference to the hibernateTransaction at that point. The CacheSynchronization only uses that reference for beforeTransactionCompletion and afterTransactionCompletion calls. The beforeTransactionCompletion works because the SessionImpl.beforeTransactionCompletion call doesn't check if the tx is null, while the afterTransactionCompletion does.

Environment

JBoss 4.0.3SP1 under Windows XP

Activity

Show:
Steve Ebersole
January 30, 2008, 12:55 PM

There seem to be 2 approaches to solving this:
1) skip the checks about null hibernateTransaction
2) make sure a hibernateTransaction is present in these scenarios (whenever we register a synch should be a viable trigger event).

Steve Ebersole
January 30, 2008, 1:15 PM

qualification of "whenever we register a synch should be a viable trigger event"...

specifically talking about the code (currently) in org.hibernate.jdbc.JDBCContext#registerSynchronizationIfPossible (~ line 169) where we register the JTA synch:

tx.registerSynchronization( new CacheSynchronization(owner, this, tx, null) );
isTransactionCallbackRegistered = true;
log.debug("successfully registered Synchronization");
return true;

(note that the null param to the CacheSynchronization ctor here is supposed to be the hibernateTransaction...)

becoming something like:

Transaction hibernateTransaction = this.hibernateTransaction;
if ( hibernateTransaction == null ) {
hibernateTransaction = owner.getFactory().getSettings().getTransactionFactory().createTransaction( this, owner );
}
tx.registerSynchronization( new CacheSynchronization(owner, this, tx, hibernateTransaction) );
isTransactionCallbackRegistered = true;
if ( this.hibernateTransaction == null ) {
this.hibernateTransaction = hibernateTransaction;
}
log.debug("successfully registered Synchronization");
return true;

The difference being that the hibernateTransaction is no longer null in these JTA scenarios we are discussing...

Steve Ebersole
February 7, 2008, 4:11 AM

trunk / 3.2

the code which registers the Hibernate synch was changed to also now create a Hibernate Transaction instance at the same time...

Steve Ebersole
March 21, 2011, 7:05 PM

Bulk closing stale resolved issues

Assignee

Steve Ebersole

Reporter

Eric Sword

Fix versions

Labels

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Components

Affects versions

Priority

Major
Configure