Skip to content

Commit e4e76ba

Browse files
dreab8sebersole
authored andcommitted
HHH-9765 - Re-introduce ExceptionMapper, ManagedFlushChecker and AfterCompletionAction
1 parent 2827a59 commit e4e76ba

File tree

14 files changed

+382
-68
lines changed

14 files changed

+382
-68
lines changed

hibernate-core/src/main/java/org/hibernate/engine/spi/SessionOwner.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
*/
2424
package org.hibernate.engine.spi;
2525

26+
import org.hibernate.resource.transaction.backend.jta.internal.synchronization.AfterCompletionAction;
27+
import org.hibernate.resource.transaction.backend.jta.internal.synchronization.ExceptionMapper;
28+
import org.hibernate.resource.transaction.backend.jta.internal.synchronization.ManagedFlushChecker;
29+
2630
/**
2731
* The contract for a Session owner. Typically this is something that wraps the Session.
2832
*
@@ -37,4 +41,10 @@ public interface SessionOwner {
3741
* @return {@literal true}/{@literal false} appropriately.
3842
*/
3943
public boolean shouldAutoCloseSession();
44+
45+
public ExceptionMapper getExceptionMapper();
46+
47+
public AfterCompletionAction getAfterCompletionAction();
48+
49+
public ManagedFlushChecker getManagedFlushChecker();
4050
}

hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java

Lines changed: 105 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
import org.hibernate.SharedSessionBuilder;
7676
import org.hibernate.SimpleNaturalIdLoadAccess;
7777
import org.hibernate.Transaction;
78+
import org.hibernate.TransactionException;
7879
import org.hibernate.TransientObjectException;
7980
import org.hibernate.TypeHelper;
8081
import org.hibernate.UnknownProfileException;
@@ -101,7 +102,7 @@
101102
import org.hibernate.engine.spi.SessionFactoryImplementor;
102103
import org.hibernate.engine.spi.SessionOwner;
103104
import org.hibernate.engine.spi.Status;
104-
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
105+
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
105106
import org.hibernate.engine.transaction.spi.TransactionObserver;
106107
import org.hibernate.event.service.spi.EventListenerGroup;
107108
import org.hibernate.event.service.spi.EventListenerRegistry;
@@ -157,6 +158,9 @@
157158
import org.hibernate.resource.jdbc.spi.StatementInspector;
158159
import org.hibernate.resource.transaction.TransactionCoordinator;
159160
import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl;
161+
import org.hibernate.resource.transaction.backend.jta.internal.synchronization.AfterCompletionAction;
162+
import org.hibernate.resource.transaction.backend.jta.internal.synchronization.ExceptionMapper;
163+
import org.hibernate.resource.transaction.backend.jta.internal.synchronization.ManagedFlushChecker;
160164
import org.hibernate.resource.transaction.spi.TransactionStatus;
161165
import org.hibernate.stat.SessionStatistics;
162166
import org.hibernate.stat.internal.SessionStatisticsImpl;
@@ -222,6 +226,10 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
222226

223227
private transient JdbcSessionContext jdbcSessionContext;
224228

229+
private transient ExceptionMapper exceptionMapper;
230+
private transient ManagedFlushChecker managedFlushChecker;
231+
private transient AfterCompletionAction afterCompletionAction;
232+
225233
/**
226234
* Constructor used for openSession(...) processing, as well as construction
227235
* of sessions for getCurrentSession().
@@ -264,6 +272,8 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
264272
this.autoCloseSessionEnabled = autoCloseSessionEnabled;
265273
this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
266274

275+
initializeFromSessionOwner( sessionOwner );
276+
267277
if ( statementInspector == null ) {
268278
this.statementInspector = new StatementInspector() {
269279
@Override
@@ -355,6 +365,34 @@ public void afterCompletion(boolean successful, boolean delayed) {
355365

356366
}
357367

368+
private void initializeFromSessionOwner(SessionOwner sessionOwner) {
369+
if ( sessionOwner != null ) {
370+
if ( sessionOwner.getExceptionMapper() != null ) {
371+
exceptionMapper = sessionOwner.getExceptionMapper();
372+
}
373+
else {
374+
exceptionMapper = STANDARD_EXCEPTION_MAPPER;
375+
}
376+
if ( sessionOwner.getAfterCompletionAction() != null ) {
377+
afterCompletionAction = sessionOwner.getAfterCompletionAction();
378+
}
379+
else {
380+
afterCompletionAction = STANDARD_AFTER_COMPLETION_ACTION;
381+
}
382+
if ( sessionOwner.getManagedFlushChecker() != null ) {
383+
managedFlushChecker = sessionOwner.getManagedFlushChecker();
384+
}
385+
else {
386+
managedFlushChecker = STANDARD_MANAGED_FLUSH_CHECKER;
387+
}
388+
}
389+
else {
390+
exceptionMapper = STANDARD_EXCEPTION_MAPPER;
391+
afterCompletionAction = STANDARD_AFTER_COMPLETION_ACTION;
392+
managedFlushChecker = STANDARD_MANAGED_FLUSH_CHECKER;
393+
}
394+
}
395+
358396
@Override
359397
public SharedSessionBuilder sessionWithOptions() {
360398
return new SharedSessionBuilderImpl( this );
@@ -707,7 +745,7 @@ private void fireLock(String entityName, Object object, LockOptions options) {
707745
fireLock( new LockEvent( entityName, object, options, this ) );
708746
}
709747

710-
private void fireLock( Object object, LockOptions options) {
748+
private void fireLock(Object object, LockOptions options) {
711749
fireLock( new LockEvent( object, options, this ) );
712750
}
713751

@@ -1209,7 +1247,8 @@ public void flush() throws HibernateException {
12091247
public void forceFlush(EntityEntry entityEntry) throws HibernateException {
12101248
errorIfClosed();
12111249
if ( LOG.isDebugEnabled() ) {
1212-
LOG.debugf( "Flushing to force deletion of re-saved object: %s",
1250+
LOG.debugf(
1251+
"Flushing to force deletion of re-saved object: %s",
12131252
MessageHelper.infoString( entityEntry.getPersister(), entityEntry.getId(), getFactory() ) );
12141253
}
12151254

@@ -1293,7 +1332,7 @@ public int executeNativeUpdate(NativeSQLQuerySpecification nativeQuerySpecificat
12931332
} finally {
12941333
afterOperation( success );
12951334
delayedAfterCompletion();
1296-
}
1335+
}
12971336
return result;
12981337
}
12991338

@@ -2148,6 +2187,8 @@ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFound
21482187
this.jdbcSessionContext = new JdbcSessionContextImpl( factory, statementInspector );
21492188
sessionOwner = (SessionOwner) ois.readObject();
21502189

2190+
initializeFromSessionOwner( sessionOwner );
2191+
21512192
jdbcCoordinator = JdbcCoordinatorImpl.deserialize( ois, this );
21522193

21532194
this.transactionCoordinator = getTransactionCoordinatorBuilder().buildTransactionCoordinator( jdbcCoordinator, this );
@@ -2239,6 +2280,8 @@ public void beforeTransactionCompletion() {
22392280
public void afterTransactionCompletion(boolean successful, boolean delayed) {
22402281
LOG.tracef( "SessionImpl#afterTransactionCompletion(successful=%s, delayed=%s)", successful, delayed );
22412282

2283+
afterCompletionAction.doAction( successful );
2284+
22422285
persistenceContext.afterTransactionCompletion();
22432286
actionQueue.afterTransactionCompletion( successful );
22442287

@@ -2834,24 +2877,65 @@ public void afterTransactionBegin() {
28342877

28352878
@Override
28362879
public void flushBeforeTransactionCompletion() {
2837-
boolean flush = false;
2880+
boolean flush = isTransactionFlushable() && managedFlushChecker.shouldDoManagedFlush( this );
28382881
try {
2839-
flush = (!isFlushModeNever() &&
2840-
!flushBeforeCompletionEnabled) || (
2841-
!isClosed()
2842-
&& !isFlushModeNever()
2843-
&& flushBeforeCompletionEnabled
2844-
&& !JtaStatusHelper.isRollback(
2845-
getSessionFactory().getSettings()
2846-
.getJtaPlatform()
2847-
.getCurrentStatus()
2848-
));
2849-
}
2850-
catch (SystemException se) {
2851-
throw new HibernateException( "could not determine transaction status in beforeCompletion()", se );
2852-
}
2853-
if ( flush ) {
2854-
managedFlush();
2882+
if ( flush ) {
2883+
managedFlush();
2884+
}
28552885
}
2886+
catch (HibernateException he) {
2887+
throw exceptionMapper.mapManagedFlushFailure( "error during managed flush", he );
2888+
}
2889+
catch (RuntimeException re) {
2890+
throw exceptionMapper.mapManagedFlushFailure( "error during managed flush", re );
2891+
}
2892+
}
2893+
2894+
private boolean isTransactionFlushable() {
2895+
if ( currentHibernateTransaction == null ) {
2896+
// assume it is flushable - CMT, auto-commit, etc
2897+
return true;
2898+
}
2899+
final TransactionStatus status = currentHibernateTransaction.getStatus();
2900+
return status == TransactionStatus.ACTIVE || status ==TransactionStatus.COMMITTING;
2901+
}
2902+
2903+
private static final ExceptionMapper STANDARD_EXCEPTION_MAPPER = new ExceptionMapper() {
2904+
@Override
2905+
public RuntimeException mapStatusCheckFailure(String message, SystemException systemException) {
2906+
return new TransactionException(
2907+
"could not determine transaction status in beforeCompletion()",
2908+
systemException
2909+
);
2910+
}
2911+
2912+
@Override
2913+
public RuntimeException mapManagedFlushFailure(String message, RuntimeException failure) {
2914+
LOG.unableToPerformManagedFlush( failure.getMessage() );
2915+
return failure;
2916+
}
2917+
};
2918+
2919+
private static final AfterCompletionAction STANDARD_AFTER_COMPLETION_ACTION = new AfterCompletionAction() {
2920+
@Override
2921+
public void doAction(boolean successful) {
2922+
// nothing to do by default.
2923+
}
2924+
};
2925+
2926+
private static final ManagedFlushChecker STANDARD_MANAGED_FLUSH_CHECKER = new ManagedFlushChecker() {
2927+
@Override
2928+
public boolean shouldDoManagedFlush(SessionImpl session) {
2929+
boolean isFlushModeNever = session.isFlushModeNever();
2930+
return (!isFlushModeNever &&
2931+
!session.flushBeforeCompletionEnabled) ||
2932+
!session.isClosed()
2933+
&& !isFlushModeNever
2934+
&& session.flushBeforeCompletionEnabled;
2935+
}
2936+
};
2937+
2938+
private JtaPlatform getJtaPlatform() {
2939+
return factory.getServiceRegistry().getService( JtaPlatform.class );
28562940
}
28572941
}

hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
import org.hibernate.engine.spi.QueryParameters;
6262
import org.hibernate.engine.spi.SessionEventListenerManager;
6363
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
64+
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
6465
import org.hibernate.id.IdentifierGeneratorHelper;
6566
import org.hibernate.loader.criteria.CriteriaLoader;
6667
import org.hibernate.loader.custom.CustomLoader;
@@ -772,9 +773,7 @@ public void flushBeforeTransactionCompletion() {
772773
!isClosed()
773774
&& !isFlushModeNever()
774775
&& !JtaStatusHelper.isRollback(
775-
factory.getSettings()
776-
.getJtaPlatform()
777-
.getCurrentStatus()
776+
getJtaPlatform().getCurrentStatus()
778777
));
779778
}
780779
catch (SystemException se) {
@@ -784,4 +783,8 @@ public void flushBeforeTransactionCompletion() {
784783
managedFlush();
785784
}
786785
}
786+
787+
private JtaPlatform getJtaPlatform() {
788+
return factory.getServiceRegistry().getService( JtaPlatform.class );
789+
}
787790
}

hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/JdbcResourceLocalTransactionCoordinatorImpl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.hibernate.resource.transaction.TransactionCoordinatorBuilder;
3939
import org.hibernate.resource.transaction.backend.jdbc.spi.JdbcResourceTransaction;
4040
import org.hibernate.resource.transaction.backend.jdbc.spi.JdbcResourceTransactionAccess;
41+
import org.hibernate.resource.transaction.backend.jta.internal.synchronization.ExceptionMapper;
4142
import org.hibernate.resource.transaction.internal.SynchronizationRegistryStandardImpl;
4243
import org.hibernate.resource.transaction.spi.TransactionCoordinatorOwner;
4344
import org.hibernate.resource.transaction.spi.TransactionStatus;

hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/JtaTransactionAdapterTransactionManagerImpl.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
*/
2424
package org.hibernate.resource.transaction.backend.jta.internal;
2525

26-
import javax.transaction.Status;
2726
import javax.transaction.SystemException;
2827
import javax.transaction.TransactionManager;
2928

@@ -41,15 +40,11 @@ public class JtaTransactionAdapterTransactionManagerImpl implements JtaTransacti
4140
private static final Logger log = Logger.getLogger( JtaTransactionAdapterTransactionManagerImpl.class );
4241

4342
private final TransactionManager transactionManager;
44-
private final JtaTransactionCoordinatorImpl transactionCoordinator;
4543

4644
private boolean initiator;
4745

48-
public JtaTransactionAdapterTransactionManagerImpl(
49-
TransactionManager transactionManager,
50-
JtaTransactionCoordinatorImpl transactionCoordinator) throws SystemException {
46+
public JtaTransactionAdapterTransactionManagerImpl(TransactionManager transactionManager) {
5147
this.transactionManager = transactionManager;
52-
this.transactionCoordinator = transactionCoordinator;
5348
}
5449

5550
@Override
@@ -73,8 +68,6 @@ public void begin() {
7368
@Override
7469
public void commit() {
7570
try {
76-
this.transactionCoordinator.getTransactionCoordinatorOwner().flushBeforeTransactionCompletion();
77-
7871
if ( initiator ) {
7972
initiator = false;
8073
log.trace( "Calling TransactionManager#commit" );

hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/JtaTransactionAdapterUserTransactionImpl.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,11 @@
2626
import javax.transaction.SystemException;
2727
import javax.transaction.UserTransaction;
2828

29+
import org.jboss.logging.Logger;
30+
2931
import org.hibernate.TransactionException;
30-
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
3132
import org.hibernate.resource.transaction.spi.TransactionStatus;
3233

33-
import org.jboss.logging.Logger;
34-
3534
/**
3635
* JtaTransactionAdapter for coordinating with the JTA UserTransaction
3736
*
@@ -41,16 +40,12 @@ public class JtaTransactionAdapterUserTransactionImpl implements JtaTransactionA
4140
private static final Logger log = Logger.getLogger( JtaTransactionAdapterUserTransactionImpl.class );
4241

4342
private final UserTransaction userTransaction;
44-
private final JtaTransactionCoordinatorImpl transactionCoordinator;
4543

4644

4745
private boolean initiator;
4846

49-
public JtaTransactionAdapterUserTransactionImpl(
50-
UserTransaction userTransaction,
51-
JtaTransactionCoordinatorImpl transactionCoordinator) {
47+
public JtaTransactionAdapterUserTransactionImpl(UserTransaction userTransaction) {
5248
this.userTransaction = userTransaction;
53-
this.transactionCoordinator = transactionCoordinator;
5449
}
5550

5651
@Override
@@ -74,8 +69,6 @@ public void begin() {
7469
@Override
7570
public void commit() {
7671
try {
77-
this.transactionCoordinator.getTransactionCoordinatorOwner().flushBeforeTransactionCompletion();
78-
7972
if ( initiator ) {
8073
initiator = false;
8174
log.trace( "Calling UserTransaction#commit" );

0 commit comments

Comments
 (0)