I debugged for a while and collected the following information: The result set is closed after the load operation has completed by the SessionImpl.afterOperation() method, because the transaction coordinater returns false when asked isTransactionInProgress():
Code:
public void afterOperation(boolean success) {
if ( ! transactionCoordinator.isTransactionInProgress() ) {
transactionCoordinator.afterNonTransactionalQuery( success );
}
}
In that case TransactionCoordinater cleans up:
Code:
public void afterNonTransactionalQuery(boolean success) {
// check to see if the connection is in auto-commit mode (no connection means aggressive connection
// release outside a JTA transaction context, so MUST be autocommit mode)
boolean isAutocommit = getJdbcCoordinator().getLogicalConnection().isAutoCommit();
getJdbcCoordinator().afterTransaction();
if ( isAutocommit ) {
for ( TransactionObserver observer : observers ) {
observer.afterCompletion( success, this.getTransaction() );
}
}
}
where JdbcCoordinater.afterTransaction() closes all Statements and ResultSets that were opened by during the current session. Apparently the problem is, that transactionCoordinator.isTransactionInProgress() returns false. The following code is executed:
Code:
public boolean isTransactionInProgress() {
return getTransaction().isActive() && getTransaction().getJoinStatus() == JoinStatus.JOINED;
}
Here getTransaction().isActive() returns false. The instance org.hibernate.engine.transaction.internal.jta.JtaTransaction checks:
Code:
public boolean isActive() throws HibernateException {
if ( getLocalStatus() != LocalStatus.ACTIVE ) {
return false;
}
final int status;
try {
status = userTransaction.getStatus();
}
catch ( SystemException se ) {
throw new TransactionException( "Could not determine transaction status: ", se );
}
return JtaStatusHelper.isActive( status );
}
Unfortunately, getLocalStatus() returns "NOT_ACTIVE" which causes the check to return false.
I wonder if the method JtaTransaction.isActive() has a bug because it checks its local status member. The local status member is set to "ACTIVE" only when the begin() method of the transaction instance is called explicitly. However, I thought that if JTA user transactions are used, then someone has not to care about Hibernate transactions. Begin/Commit/Rollback is signalled on the user transaction instance.
As a workaround I added the following lines of code to the HQL test:
Code:
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
This seems to work.
Could some initiate comment on this please?
TIA
--Stefan