HHH-9760 - TransactionImpl itself should not be throwing new TransactionExceptions
This commit is contained in:
parent
f8186e10c2
commit
88a6e4ba27
|
@ -506,9 +506,9 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void afterTransactionCompletion(boolean successful) {
|
||||
public void afterTransactionCompletion(boolean successful, boolean delayed) {
|
||||
afterTransaction();
|
||||
owner.afterTransactionCompletion( successful );
|
||||
owner.afterTransactionCompletion( successful, delayed );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -541,7 +541,7 @@ public class JdbcCoordinatorImpl implements JdbcCoordinator {
|
|||
* JDK deserialization hook
|
||||
*
|
||||
* @param ois The stream into which to write our state
|
||||
* @param JdbcSessionOwner The Jdbc Session owner which owns the JdbcCoordinatorImpl to be deserialized.
|
||||
* @param owner The Jdbc Session owner which owns the JdbcCoordinatorImpl to be deserialized.
|
||||
*
|
||||
* @return The deserialized JdbcCoordinatorImpl
|
||||
*
|
||||
|
|
|
@ -80,9 +80,6 @@ public class TransactionImpl implements Transaction {
|
|||
try {
|
||||
this.transactionDriverControl.commit();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new TransactionException( "commit failed", e );
|
||||
}
|
||||
finally {
|
||||
invalidate();
|
||||
}
|
||||
|
@ -100,9 +97,6 @@ public class TransactionImpl implements Transaction {
|
|||
try {
|
||||
this.transactionDriverControl.rollback();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new TransactionException( "rollback failed", e );
|
||||
}
|
||||
finally {
|
||||
invalidate();
|
||||
}
|
||||
|
|
|
@ -47,6 +47,6 @@ public interface TransactionObserver {
|
|||
*
|
||||
* @param successful Was the transaction successful?
|
||||
*/
|
||||
public void afterCompletion(boolean successful);
|
||||
public void afterCompletion(boolean successful, boolean delayed);
|
||||
}
|
||||
|
||||
|
|
|
@ -335,9 +335,9 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(boolean successful) {
|
||||
afterTransactionCompletion( successful );
|
||||
if ( isOpen() && autoCloseSessionEnabled ) {
|
||||
public void afterCompletion(boolean successful, boolean delayed) {
|
||||
afterTransactionCompletion( successful, delayed );
|
||||
if ( !isClosed() && autoCloseSessionEnabled ) {
|
||||
managedClose();
|
||||
}
|
||||
}
|
||||
|
@ -2248,7 +2248,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
|
||||
@Override
|
||||
public void beforeTransactionCompletion() {
|
||||
LOG.trace( "before transaction completion" );
|
||||
LOG.tracef( "SessionImpl#beforeTransactionCompletion()" );
|
||||
flushBeforeTransactionCompletion();
|
||||
actionQueue.beforeTransactionCompletion();
|
||||
try {
|
||||
|
@ -2260,9 +2260,8 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
}
|
||||
|
||||
@Override
|
||||
public void afterTransactionCompletion(boolean successful) {
|
||||
|
||||
LOG.trace( "after transaction completion" );
|
||||
public void afterTransactionCompletion(boolean successful, boolean delayed) {
|
||||
LOG.tracef( "SessionImpl#afterTransactionCompletion(successful=%s, delayed=%s)", successful, delayed );
|
||||
|
||||
persistenceContext.afterTransactionCompletion();
|
||||
actionQueue.afterTransactionCompletion( successful );
|
||||
|
@ -2280,8 +2279,10 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
|
|||
LOG.exceptionInAfterTransactionCompletionInterceptor( t );
|
||||
}
|
||||
|
||||
if ( shouldAutoClose() && !isClosed() ) {
|
||||
managedClose();
|
||||
if ( !delayed ) {
|
||||
if ( shouldAutoClose() && !isClosed() ) {
|
||||
managedClose();
|
||||
}
|
||||
}
|
||||
|
||||
if ( autoClear ) {
|
||||
|
|
|
@ -774,9 +774,8 @@ public class StatelessSessionImpl extends AbstractSessionImpl implements Statele
|
|||
}
|
||||
|
||||
@Override
|
||||
public void afterTransactionCompletion(boolean successful) {
|
||||
if ( shouldAutoClose()
|
||||
&& !isClosed() ) {
|
||||
public void afterTransactionCompletion(boolean successful, boolean delayed) {
|
||||
if ( shouldAutoClose() && !isClosed() ) {
|
||||
managedClose();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,8 +55,9 @@ public interface JdbcSessionOwner {
|
|||
* An after-completion callback to the owner.
|
||||
*
|
||||
* @param successful Was the transaction successful?
|
||||
* @param delayed Is this a delayed after transaction completion call (aka after a timeout)?
|
||||
*/
|
||||
public void afterTransactionCompletion(boolean successful);
|
||||
public void afterTransactionCompletion(boolean successful, boolean delayed);
|
||||
|
||||
public void flushBeforeTransactionCompletion();
|
||||
}
|
||||
|
|
|
@ -171,9 +171,9 @@ public class JdbcResourceLocalTransactionCoordinatorImpl implements TransactionC
|
|||
final int statusToSend = successful ? Status.STATUS_COMMITTED : Status.STATUS_UNKNOWN;
|
||||
synchronizationRegistry.notifySynchronizationsAfterTransactionCompletion( statusToSend );
|
||||
|
||||
transactionCoordinatorOwner.afterTransactionCompletion( successful );
|
||||
transactionCoordinatorOwner.afterTransactionCompletion( successful, false );
|
||||
for ( TransactionObserver observer : observers ) {
|
||||
observer.afterCompletion( successful );
|
||||
observer.afterCompletion( successful, false );
|
||||
}
|
||||
invalidateDelegate();
|
||||
}
|
||||
|
|
|
@ -304,7 +304,8 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
|
|||
public void beforeCompletion() {
|
||||
try {
|
||||
transactionCoordinatorOwner.beforeTransactionCompletion();
|
||||
}catch (Exception e){
|
||||
}
|
||||
catch (Exception e) {
|
||||
physicalTransactionDelegate.markRollbackOnly();
|
||||
}
|
||||
synchronizationRegistry.notifySynchronizationsBeforeTransactionCompletion();
|
||||
|
@ -315,19 +316,26 @@ public class JtaTransactionCoordinatorImpl implements TransactionCoordinator, Sy
|
|||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(boolean successful) {
|
||||
public void afterCompletion(boolean successful, boolean delayed) {
|
||||
if ( !transactionCoordinatorOwner.isActive() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int statusToSend = successful ? Status.STATUS_COMMITTED : Status.STATUS_UNKNOWN;
|
||||
synchronizationRegistry.notifySynchronizationsAfterTransactionCompletion( statusToSend );
|
||||
|
||||
transactionCoordinatorOwner.afterTransactionCompletion( successful );
|
||||
// afterCompletionAction.doAction( this, statusToSend );
|
||||
|
||||
transactionCoordinatorOwner.afterTransactionCompletion( successful, delayed );
|
||||
|
||||
for ( TransactionObserver observer : observers ) {
|
||||
observer.afterCompletion( successful );
|
||||
observer.afterCompletion( successful, delayed );
|
||||
}
|
||||
|
||||
if ( physicalTransactionDelegate != null ) {
|
||||
physicalTransactionDelegate.invalidate();
|
||||
}
|
||||
|
||||
physicalTransactionDelegate = null;
|
||||
synchronizationRegistered = false;
|
||||
}
|
||||
|
|
|
@ -68,13 +68,17 @@ public class SynchronizationCallbackCoordinatorNonTrackingImpl implements Synchr
|
|||
|
||||
@Override
|
||||
public void afterCompletion(int status) {
|
||||
doAfterCompletion( JtaStatusHelper.isCommitted( status ) );
|
||||
log.tracef( "Synchronization coordinator: afterCompletion(status=%s)", status );
|
||||
doAfterCompletion( JtaStatusHelper.isCommitted( status ), false );
|
||||
}
|
||||
|
||||
protected void doAfterCompletion(boolean successful) {
|
||||
protected void doAfterCompletion(boolean successful, boolean delayed) {
|
||||
log.tracef( "Synchronization coordinator: doAfterCompletion(successful=%s, delayed=%s)", successful, delayed );
|
||||
|
||||
try {
|
||||
target.afterCompletion( successful );
|
||||
}finally {
|
||||
target.afterCompletion( successful, delayed );
|
||||
}
|
||||
finally {
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,13 +39,11 @@ import static org.hibernate.internal.CoreLogging.messageLogger;
|
|||
public class SynchronizationCallbackCoordinatorTrackingImpl extends SynchronizationCallbackCoordinatorNonTrackingImpl {
|
||||
private static final CoreMessageLogger log = messageLogger( SynchronizationCallbackCoordinatorTrackingImpl.class );
|
||||
|
||||
// magic number :(
|
||||
private static final long NO_THREAD_ID = Long.MIN_VALUE;
|
||||
|
||||
private volatile long registrationThreadId = NO_THREAD_ID;
|
||||
private volatile long registrationThreadId;
|
||||
private volatile boolean delayedCompletionHandling;
|
||||
|
||||
public SynchronizationCallbackCoordinatorTrackingImpl(SynchronizationCallbackTarget target) {
|
||||
// super ctor calls reset() followed by pulse()
|
||||
super( target );
|
||||
}
|
||||
|
||||
|
@ -57,13 +55,16 @@ public class SynchronizationCallbackCoordinatorTrackingImpl extends Synchronizat
|
|||
// 2) after "after completion" handling is finished.
|
||||
//
|
||||
// Here we use that to "clear out" all 'delayed after-completion" state. The registrationThreadId will
|
||||
// "lazily" be re-populated on the next synchronizationRegistered call to allow for the potential of the next Session transaction
|
||||
// occurring on a different thread (though that transaction would need to completely operate on that thread).
|
||||
// "lazily" be re-populated on the next synchronizationRegistered call to allow for the potential of the
|
||||
// next Session transaction occurring on a different thread (though that transaction would need to completely
|
||||
// operate on that thread).
|
||||
delayedCompletionHandling = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(int status) {
|
||||
log.tracef( "Synchronization coordinator: afterCompletion(status=%s)", status );
|
||||
|
||||
// The whole concept of "tracking" comes down to this code block..
|
||||
// Essentially we need to see if we can process the callback immediately. So here we check whether the
|
||||
// current call is happening on the same thread as the thread under which we registered the Synchronization.
|
||||
|
@ -79,30 +80,29 @@ public class SynchronizationCallbackCoordinatorTrackingImpl extends Synchronizat
|
|||
// check for it in SessionImpl. See HHH-7910.
|
||||
delayedCompletionHandling = true;
|
||||
|
||||
// todo : update code to use message logger
|
||||
//log.rollbackFromBackgroundThread( status );
|
||||
log.warn( "Rollback from background thread (update code to use message logger)" );
|
||||
log.rollbackFromBackgroundThread( status );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise, do the callback immediately
|
||||
doAfterCompletion( JtaStatusHelper.isCommitted( status ) );
|
||||
doAfterCompletion( JtaStatusHelper.isCommitted( status ), false );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void synchronizationRegistered() {
|
||||
if ( registrationThreadId == NO_THREAD_ID ) {
|
||||
registrationThreadId = Thread.currentThread().getId();
|
||||
}
|
||||
registrationThreadId = Thread.currentThread().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processAnyDelayedAfterCompletion() {
|
||||
if ( delayedCompletionHandling ) {
|
||||
// false here because, as discussed above, the delayed logic should only ever occur during rollback
|
||||
delayedCompletionHandling = false;
|
||||
doAfterCompletion( false );
|
||||
|
||||
// false here (rather than how we used to keep and check the status) because as discussed above
|
||||
// the delayed logic should only ever occur during rollback
|
||||
doAfterCompletion( false, true );
|
||||
|
||||
// NOTE : doAfterCompletion calls reset
|
||||
throw new HibernateException( "Transaction was rolled back in a different thread!" );
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ package org.hibernate.resource.transaction.backend.jta.internal.synchronization;
|
|||
public interface SynchronizationCallbackTarget {
|
||||
/**
|
||||
* Is the callback target still active? Generally this is checked by the caller prior to calling
|
||||
* {@link #beforeCompletion()} or {@link #afterCompletion(boolean)}
|
||||
* {@link #beforeCompletion} or {@link #afterCompletion}
|
||||
*
|
||||
* @return {@code true} indicates the target is active; {@code false} indicates it is not.
|
||||
*/
|
||||
|
@ -72,5 +72,5 @@ public interface SynchronizationCallbackTarget {
|
|||
*
|
||||
* @see javax.transaction.Synchronization#afterCompletion
|
||||
*/
|
||||
void afterCompletion(boolean successful);
|
||||
void afterCompletion(boolean successful, boolean delayed);
|
||||
}
|
||||
|
|
|
@ -59,8 +59,9 @@ public interface TransactionCoordinatorOwner {
|
|||
* An after-completion callback from the coordinator to its owner.
|
||||
*
|
||||
* @param successful Was the transaction successful?
|
||||
* @param delayed Is this a delayed after transaction completion call (aka after a timeout)?
|
||||
*/
|
||||
public void afterTransactionCompletion(boolean successful);
|
||||
public void afterTransactionCompletion(boolean successful, boolean delayed);
|
||||
|
||||
public JdbcSessionOwner getJdbcSessionOwner();
|
||||
|
||||
|
|
|
@ -291,8 +291,8 @@ public class EntityTest extends BaseNonConfigCoreFunctionalTestCase {
|
|||
tx.commit();
|
||||
fail( "Optimistic locking should work" );
|
||||
}
|
||||
catch (TransactionException e) {
|
||||
assertTrue( e.getCause() instanceof StaleStateException );
|
||||
catch (StaleStateException expected) {
|
||||
// expected exception
|
||||
}
|
||||
finally {
|
||||
if ( tx != null ) {
|
||||
|
|
|
@ -120,7 +120,7 @@ public class ImmutableTest extends BaseCoreFunctionalTestCase {
|
|||
fail();
|
||||
}
|
||||
catch (HibernateException e) {
|
||||
assertTrue(e.getCause().getMessage().contains("changed an immutable collection instance"));
|
||||
assertTrue(e.getMessage().contains("changed an immutable collection instance"));
|
||||
log.debug("success");
|
||||
}
|
||||
s.close();
|
||||
|
@ -137,7 +137,7 @@ public class ImmutableTest extends BaseCoreFunctionalTestCase {
|
|||
tx.commit();
|
||||
fail();
|
||||
} catch (HibernateException e) {
|
||||
assertTrue(e.getCause().getMessage().contains("changed an immutable collection instance"));
|
||||
assertTrue(e.getMessage().contains("changed an immutable collection instance"));
|
||||
log.debug("success");
|
||||
}
|
||||
s.close();
|
||||
|
|
|
@ -195,8 +195,8 @@ public class MultiPathCascadeTest extends BaseCoreFunctionalTestCase {
|
|||
s.getTransaction().commit();
|
||||
fail( "should have thrown TransientObjectException" );
|
||||
}
|
||||
catch (TransactionException e) {
|
||||
assertTrue( e.getCause() instanceof TransientObjectException );
|
||||
catch (TransientObjectException expected) {
|
||||
// expected
|
||||
}
|
||||
finally {
|
||||
s.getTransaction().rollback();
|
||||
|
@ -244,8 +244,8 @@ public class MultiPathCascadeTest extends BaseCoreFunctionalTestCase {
|
|||
s.getTransaction().commit();
|
||||
fail( "should have thrown TransientObjectException" );
|
||||
}
|
||||
catch (TransactionException e) {
|
||||
assertTrue( e.getCause() instanceof TransientObjectException );
|
||||
catch (TransientObjectException expected) {
|
||||
// expected
|
||||
}
|
||||
finally {
|
||||
s.getTransaction().rollback();
|
||||
|
@ -293,8 +293,8 @@ public class MultiPathCascadeTest extends BaseCoreFunctionalTestCase {
|
|||
s.getTransaction().commit();
|
||||
fail( "should have thrown TransientObjectException" );
|
||||
}
|
||||
catch (TransactionException e) {
|
||||
assertTrue( e.getCause() instanceof TransientObjectException );
|
||||
catch (TransientObjectException expected) {
|
||||
// expected
|
||||
}
|
||||
finally {
|
||||
s.getTransaction().rollback();
|
||||
|
|
|
@ -33,15 +33,18 @@ public class JournalingTransactionObserver implements TransactionObserver {
|
|||
private int beforeCompletions = 0;
|
||||
private int afterCompletions = 0;
|
||||
|
||||
@Override
|
||||
public void afterBegin() {
|
||||
begins++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeCompletion() {
|
||||
beforeCompletions++;
|
||||
}
|
||||
|
||||
public void afterCompletion(boolean successful) {
|
||||
@Override
|
||||
public void afterCompletion(boolean successful, boolean delayed) {
|
||||
afterCompletions++;
|
||||
}
|
||||
|
||||
|
|
|
@ -935,11 +935,11 @@ public abstract class AbstractEntityWithManyToManyTest extends BaseCoreFunctiona
|
|||
t.commit();
|
||||
assertFalse( isContractVersioned );
|
||||
}
|
||||
catch (TransactionException e){
|
||||
catch (StaleStateException ex) {
|
||||
t.rollback();
|
||||
assertTrue( isContractVersioned );
|
||||
if ( ! sessionFactory().getSettings().isJdbcBatchVersionedData() ) {
|
||||
assertTrue( StaleObjectStateException.class.isInstance( e.getCause() ) );
|
||||
if ( ! sessionFactory().getSessionFactoryOptions().isJdbcBatchVersionedData() ) {
|
||||
assertTrue( StaleObjectStateException.class.isInstance( ex ) );
|
||||
}
|
||||
}
|
||||
s.close();
|
||||
|
|
|
@ -1162,11 +1162,11 @@ public abstract class AbstractEntityWithOneToManyTest extends BaseCoreFunctional
|
|||
t.commit();
|
||||
assertFalse( isContractVersioned );
|
||||
}
|
||||
catch (TransactionException ex) {
|
||||
catch (StaleStateException ex) {
|
||||
t.rollback();
|
||||
assertTrue( isContractVersioned );
|
||||
if ( ! sessionFactory().getSettings().isJdbcBatchVersionedData() ) {
|
||||
assertTrue( StaleObjectStateException.class.isInstance( ex.getCause() ) );
|
||||
if ( ! sessionFactory().getSessionFactoryOptions().isJdbcBatchVersionedData() ) {
|
||||
assertTrue( StaleObjectStateException.class.isInstance( ex ) );
|
||||
}
|
||||
}
|
||||
s.close();
|
||||
|
|
|
@ -157,17 +157,11 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
|
|||
fail( "Transaction should have timed out" );
|
||||
}
|
||||
catch (TransactionException e) {
|
||||
// Insure that the Exception is "transaction timeout expired"
|
||||
String exceptionActual = e.getCause().toString();
|
||||
String exceptionExpected = "org.hibernate.TransactionException: transaction timeout expired";
|
||||
if ( !exceptionActual.contains( exceptionExpected ) ) {
|
||||
String msg = String.format(
|
||||
"Transaction failed for the wrong reason. Expected [%s] but received [%s]",
|
||||
exceptionExpected, exceptionActual
|
||||
);
|
||||
fail( msg );
|
||||
|
||||
}
|
||||
assertTrue(
|
||||
"Transaction failed for the wrong reason. Expecting transaction timeout, but found [" +
|
||||
e.getMessage() + "]" ,
|
||||
e.getMessage().contains( "transaction timeout expired" )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,9 +70,8 @@ public class CascadeTest extends AbstractJPATest {
|
|||
s.getTransaction().commit();
|
||||
fail( "expecting TransientObjectException on flush" );
|
||||
}
|
||||
catch (TransactionException te) {
|
||||
assertTrue( te.getCause() instanceof TransientObjectException );
|
||||
log.trace( "handled expected exception", te );
|
||||
catch (TransientObjectException toe) {
|
||||
log.trace( "handled expected exception", toe );
|
||||
s.getTransaction().rollback();
|
||||
}
|
||||
finally {
|
||||
|
|
|
@ -26,18 +26,16 @@ package org.hibernate.test.ops;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.PersistentObjectException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.TransactionException;
|
||||
import org.hibernate.exception.ConstraintViolationException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
|
@ -148,9 +146,8 @@ public class CreateTest extends AbstractOperationTestCase {
|
|||
tx.commit();
|
||||
fail( "Expecting constraint failure" );
|
||||
}
|
||||
catch (TransactionException te) {
|
||||
catch (ConstraintViolationException te) {
|
||||
//verify that an exception is thrown!
|
||||
assertTrue( te.getCause() instanceof ConstraintViolationException);
|
||||
}
|
||||
tx.rollback();
|
||||
s.close();
|
||||
|
@ -165,9 +162,8 @@ public class CreateTest extends AbstractOperationTestCase {
|
|||
tx.commit();
|
||||
assertFalse(true);
|
||||
}
|
||||
catch (TransactionException te) {
|
||||
catch (ConstraintViolationException te) {
|
||||
//verify that an exception is thrown!
|
||||
assertTrue( te.getCause() instanceof ConstraintViolationException);
|
||||
}
|
||||
tx.rollback();
|
||||
s.close();
|
||||
|
|
|
@ -109,7 +109,7 @@ public class TransactionCoordinatorOwnerTestingImpl
|
|||
}
|
||||
|
||||
@Override
|
||||
public void afterTransactionCompletion(boolean successful) {
|
||||
public void afterTransactionCompletion(boolean successful, boolean delayed) {
|
||||
log.debug( "#afterTransactionCompletion called" );
|
||||
if ( successful ) {
|
||||
successfulCompletionCount++;
|
||||
|
|
|
@ -90,7 +90,7 @@ public class TransactionCoordinatorOwnerTestingImpl implements TransactionCoordi
|
|||
}
|
||||
|
||||
@Override
|
||||
public void afterTransactionCompletion(boolean successful) {
|
||||
public void afterTransactionCompletion(boolean successful, boolean delayed) {
|
||||
log.debug( "#afterTransactionCompletion called" );
|
||||
if ( successful ) {
|
||||
successfulCompletionCount++;
|
||||
|
|
|
@ -78,9 +78,8 @@ public class BeanValidationTest extends BaseEntityManagerFunctionalTestCase {
|
|||
}
|
||||
catch ( RollbackException e ) {
|
||||
final Throwable cve = e.getCause();
|
||||
assertTrue( cve instanceof PersistenceException );
|
||||
assertTrue( cve.getCause() instanceof ConstraintViolationException );
|
||||
assertEquals( 1, ( (ConstraintViolationException) cve.getCause() ).getConstraintViolations().size() );
|
||||
assertTrue( cve instanceof ConstraintViolationException );
|
||||
assertEquals( 1, ( (ConstraintViolationException) cve ).getConstraintViolations().size() );
|
||||
}
|
||||
em.close();
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.hibernate.TransientPropertyValueException;
|
|||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
import org.hibernate.testing.FailureExpected;
|
||||
|
||||
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
@ -257,10 +258,8 @@ public class MultiCircleJpaCascadeTest extends BaseEntityManagerFunctionalTestCa
|
|||
// because e is not in the process of being saved yet.
|
||||
// when HHH-6999 is fixed, this test should be changed to
|
||||
// check for g and f.g
|
||||
assertTrue( ise.getCause() instanceof TransactionException );
|
||||
Throwable cause = ise.getCause().getCause();
|
||||
assertTrue( cause instanceof TransientPropertyValueException );
|
||||
TransientPropertyValueException tpve = ( TransientPropertyValueException ) cause;
|
||||
//noinspection ThrowableResultOfMethodCallIgnored
|
||||
TransientPropertyValueException tpve = assertTyping( TransientPropertyValueException.class, ise.getCause() );
|
||||
assertEquals( E.class.getName(), tpve.getTransientEntityName() );
|
||||
assertEquals( D.class.getName(), tpve.getPropertyOwnerEntityName() );
|
||||
assertEquals( "e", tpve.getPropertyName() );
|
||||
|
|
|
@ -50,9 +50,9 @@ import static org.junit.Assert.fail;
|
|||
public class TransactionRolledBackInDifferentThreadTest extends BaseEntityManagerFunctionalTestCase {
|
||||
@Override
|
||||
protected void addConfigOptions(Map options) {
|
||||
super.addConfigOptions(options);
|
||||
TestingJtaBootstrap.prepare(options);
|
||||
options.put(AvailableSettings.TRANSACTION_TYPE, "JTA");
|
||||
super.addConfigOptions( options );
|
||||
TestingJtaBootstrap.prepare( options );
|
||||
options.put( AvailableSettings.TRANSACTION_TYPE, "JTA" );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -85,25 +85,32 @@ public class TransactionRolledBackInDifferentThreadTest extends BaseEntityManage
|
|||
em.joinTransaction();
|
||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().setRollbackOnly();
|
||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
|
||||
} catch (javax.persistence.PersistenceException e) {
|
||||
if (e.getCause() instanceof HibernateException &&
|
||||
e.getCause().getMessage().equals("Transaction was rolled back in a different thread!")) {
|
||||
}
|
||||
catch (javax.persistence.PersistenceException e) {
|
||||
if ( e.getCause() instanceof HibernateException &&
|
||||
e.getCause().getMessage().equals( "Transaction was rolled back in a different thread!" ) ) {
|
||||
/**
|
||||
* Save the exception for the main test thread to fail
|
||||
*/
|
||||
e.printStackTrace(); // show the error first
|
||||
transactionRolledBackInDifferentThreadException[0] = (HibernateException) e.getCause();
|
||||
}
|
||||
} catch (RollbackException ignored) {
|
||||
}
|
||||
catch (RollbackException ignored) {
|
||||
// expected to see RollbackException: ARJUNA016053: Could not commit transaction.
|
||||
|
||||
} catch (Throwable throwable) {
|
||||
}
|
||||
catch (Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
if (TestingJtaPlatformImpl.INSTANCE.getTransactionManager().getStatus() != Status.STATUS_NO_TRANSACTION)
|
||||
if ( TestingJtaPlatformImpl.INSTANCE.getTransactionManager()
|
||||
.getStatus() != Status.STATUS_NO_TRANSACTION ) {
|
||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
|
||||
} catch (SystemException ignore) {
|
||||
}
|
||||
}
|
||||
catch (SystemException ignore) {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -123,45 +130,56 @@ public class TransactionRolledBackInDifferentThreadTest extends BaseEntityManage
|
|||
*/
|
||||
em.joinTransaction();
|
||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
|
||||
} catch (javax.persistence.PersistenceException e) {
|
||||
if (e.getCause() instanceof HibernateException &&
|
||||
e.getCause().getMessage().equals("Transaction was rolled back in a different thread!")) {
|
||||
}
|
||||
catch (javax.persistence.PersistenceException e) {
|
||||
if ( e.getCause() instanceof HibernateException &&
|
||||
e.getCause().getMessage().equals( "Transaction was rolled back in a different thread!" ) ) {
|
||||
/**
|
||||
* Save the exception for the main test thread to fail
|
||||
*/
|
||||
e.printStackTrace(); // show the error first
|
||||
transactionRolledBackInDifferentThreadException[1] = (HibernateException) e.getCause();
|
||||
}
|
||||
} catch (Throwable throwable) {
|
||||
}
|
||||
catch (Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
if (TestingJtaPlatformImpl.INSTANCE.getTransactionManager().getStatus() != Status.STATUS_NO_TRANSACTION)
|
||||
if ( TestingJtaPlatformImpl.INSTANCE.getTransactionManager()
|
||||
.getStatus() != Status.STATUS_NO_TRANSACTION ) {
|
||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
|
||||
} catch (SystemException ignore) {
|
||||
}
|
||||
}
|
||||
catch (SystemException ignore) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Thread thread = new Thread(run1, "test thread1");
|
||||
Thread thread = new Thread( run1, "test thread1" );
|
||||
thread.start();
|
||||
thread.join();
|
||||
|
||||
Thread thread2 = new Thread(run2, "test thread2");
|
||||
Thread thread2 = new Thread( run2, "test thread2" );
|
||||
thread2.start();
|
||||
thread2.join();
|
||||
|
||||
// show failure for exception caught in run2.run()
|
||||
if (transactionRolledBackInDifferentThreadException[0] != null
|
||||
|| transactionRolledBackInDifferentThreadException[1] != null)
|
||||
if ( transactionRolledBackInDifferentThreadException[0] != null
|
||||
|| transactionRolledBackInDifferentThreadException[1] != null )
|
||||
|
||||
{
|
||||
fail("failure in test thread 1 = " +
|
||||
(transactionRolledBackInDifferentThreadException[0] != null ? transactionRolledBackInDifferentThreadException[0].getMessage() : "(none)")
|
||||
+ ", failure in test thread 2 = " +
|
||||
(transactionRolledBackInDifferentThreadException[1] != null ? transactionRolledBackInDifferentThreadException[1].getMessage() : "(none)")
|
||||
fail(
|
||||
"failure in test thread 1 = " +
|
||||
( transactionRolledBackInDifferentThreadException[0] != null ?
|
||||
transactionRolledBackInDifferentThreadException[0].getMessage() :
|
||||
"(none)" )
|
||||
+ ", failure in test thread 2 = " +
|
||||
( transactionRolledBackInDifferentThreadException[1] != null ?
|
||||
transactionRolledBackInDifferentThreadException[1].getMessage() :
|
||||
"(none)" )
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -171,7 +189,7 @@ public class TransactionRolledBackInDifferentThreadTest extends BaseEntityManage
|
|||
|
||||
@Override
|
||||
public Class[] getAnnotatedClasses() {
|
||||
return new Class[]{
|
||||
return new Class[] {
|
||||
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue