HHH-13326 : Transaction passed to Hibernate Interceptor methods is null when JTA is used

This commit is contained in:
Gail Badner 2019-03-19 21:40:32 -07:00 committed by Guillaume Smet
parent 705ecec94f
commit 883465f525
2 changed files with 27 additions and 13 deletions

View File

@ -401,17 +401,23 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
@Override
public Transaction getTransaction() throws HibernateException {
if ( getFactory().getSessionFactoryOptions().getJpaCompliance().isJpaTransactionComplianceEnabled() ) {
// JPA requires that we throw IllegalStateException if this is called
// on a JTA EntityManager
if ( getTransactionCoordinator().getTransactionCoordinatorBuilder().isJta() ) {
if ( !getFactory().getSessionFactoryOptions().isJtaTransactionAccessEnabled() ) {
throw new IllegalStateException( "A JTA EntityManager cannot use getTransaction()" );
}
if ( !isTransactionAccessible() ) {
throw new IllegalStateException(
"Transaction is not accessible when using JTA with JPA-compliant transaction access enabled"
);
}
return accessTransaction();
}
return accessTransaction();
protected boolean isTransactionAccessible() {
// JPA requires that access not be provided to the transaction when using JTA.
// This is overridden when SessionFactoryOptions isJtaTransactionAccessEnabled() is true.
if ( getFactory().getSessionFactoryOptions().getJpaCompliance().isJpaTransactionComplianceEnabled() &&
getTransactionCoordinator().getTransactionCoordinatorBuilder().isJta() &&
!getFactory().getSessionFactoryOptions().isJtaTransactionAccessEnabled() ) {
return false;
}
return true;
}
@Override

View File

@ -69,6 +69,7 @@ import org.hibernate.SessionEventListener;
import org.hibernate.SessionException;
import org.hibernate.SharedSessionBuilder;
import org.hibernate.SimpleNaturalIdLoadAccess;
import org.hibernate.Transaction;
import org.hibernate.TransientObjectException;
import org.hibernate.TypeHelper;
import org.hibernate.TypeMismatchException;
@ -2512,13 +2513,20 @@ public final class SessionImpl
private transient LobHelperImpl lobHelper;
private Transaction getTransactionIfAccessible() {
// We do not want an exception to be thrown if the transaction
// is not accessible. If the transaction is not accessible,
// then return null.
return isTransactionAccessible() ? accessTransaction() : null;
}
@Override
public void beforeTransactionCompletion() {
log.tracef( "SessionImpl#beforeTransactionCompletion()" );
flushBeforeTransactionCompletion();
actionQueue.beforeTransactionCompletion();
try {
getInterceptor().beforeTransactionCompletion( getCurrentTransaction() );
getInterceptor().beforeTransactionCompletion( getTransactionIfAccessible() );
}
catch (Throwable t) {
log.exceptionInBeforeTransactionCompletionInterceptor( t );
@ -2546,7 +2554,7 @@ public final class SessionImpl
}
try {
getInterceptor().afterTransactionCompletion( getCurrentTransaction() );
getInterceptor().afterTransactionCompletion( getTransactionIfAccessible() );
}
catch (Throwable t) {
log.exceptionInAfterTransactionCompletionInterceptor( t );
@ -2767,7 +2775,7 @@ public final class SessionImpl
}
actionQueue.beforeTransactionCompletion();
try {
getInterceptor().beforeTransactionCompletion( getCurrentTransaction() );
getInterceptor().beforeTransactionCompletion( getTransactionIfAccessible() );
}
catch (Throwable t) {
log.exceptionInBeforeTransactionCompletionInterceptor( t );
@ -3334,7 +3342,7 @@ public final class SessionImpl
@Override
public void afterTransactionBegin() {
checkOpenOrWaitingForAutoClose();
getInterceptor().afterTransactionBegin( getCurrentTransaction() );
getInterceptor().afterTransactionBegin( getTransactionIfAccessible() );
}
@Override