HHH-14503 - Migration of tests from jpa/test to orm/test/jpa

This commit is contained in:
Andrea Boriero 2021-05-03 14:28:40 +02:00
parent 4a59e2d002
commit 28d7f48019
10 changed files with 454 additions and 382 deletions

View File

@ -11,7 +11,6 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import javax.persistence.CascadeType; import javax.persistence.CascadeType;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.FetchType; import javax.persistence.FetchType;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
@ -35,7 +34,6 @@ import org.hibernate.testing.jta.TestingJtaPlatformImpl;
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
import org.hibernate.testing.orm.junit.Jpa; import org.hibernate.testing.orm.junit.Jpa;
import org.hibernate.testing.orm.junit.Setting; import org.hibernate.testing.orm.junit.Setting;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -65,266 +63,240 @@ public class CloseEntityManagerWithActiveTransactionTest {
@AfterEach @AfterEach
public void tearDown(EntityManagerFactoryScope scope) throws Exception { public void tearDown(EntityManagerFactoryScope scope) throws Exception {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
EntityManager em = scope.getEntityManagerFactory().createEntityManager();
try { try {
em.createQuery( "delete from Muffin" ).executeUpdate(); transactionManager.begin();
em.createQuery( "delete from Box" ).executeUpdate(); scope.inEntityManager(
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); em -> {
em.createQuery( "delete from Muffin" ).executeUpdate();
em.createQuery( "delete from Box" ).executeUpdate();
try {
transactionManager.commit();
}
catch (Exception e) {
throw new RuntimeException( e );
}
}
);
} }
catch (Exception e) { catch (Exception e) {
final TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager(); rollbackActiveTransaction( transactionManager );
if ( transactionManager.getTransaction() != null &&
transactionManager.getTransaction().getStatus() == Status.STATUS_ACTIVE ) {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
}
throw e; throw e;
} }
finally {
if ( em.isOpen() ) {
em.close();
}
}
} }
@Test @Test
@TestForIssue(jiraKey = "HHH-10942") @TestForIssue(jiraKey = "HHH-10942")
public void testPersistThenCloseWithAnActiveTransaction(EntityManagerFactoryScope scope) throws Exception { public void testPersistThenCloseWithAnActiveTransaction(EntityManagerFactoryScope scope) throws Exception {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
EntityManager em = scope.getEntityManagerFactory().createEntityManager();
try { try {
Box box = new Box(); transactionManager.begin();
box.setColor( "red-and-white" ); scope.inEntityManager(
em.persist( box ); em -> {
em.close(); Box box = new Box();
box.setColor( "red-and-white" );
em.persist( box );
}
);
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
} }
catch (Exception e) { catch (Exception e) {
final TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager(); rollbackActiveTransaction( transactionManager );
if ( transactionManager.getTransaction() != null && transactionManager.getTransaction()
.getStatus() == Status.STATUS_ACTIVE ) {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
}
throw e; throw e;
} }
finally { scope.inEntityManager(
if ( em.isOpen() ) { em -> {
em.close(); final List results = em.createQuery( "from Box" ).getResultList();
} assertThat( results.size(), is( 1 ) );
} }
em = scope.getEntityManagerFactory().createEntityManager(); );
try {
final List results = em.createQuery( "from Box" ).getResultList();
assertThat( results.size(), is( 1 ) );
}
finally {
em.close();
}
} }
@Test @Test
@TestForIssue(jiraKey = "HHH-11166") @TestForIssue(jiraKey = "HHH-11166")
public void testMergeThenCloseWithAnActiveTransaction(EntityManagerFactoryScope scope) throws Exception { public void testMergeThenCloseWithAnActiveTransaction(EntityManagerFactoryScope scope) throws Exception {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
EntityManager em = scope.getEntityManagerFactory().createEntityManager();
try { try {
transactionManager.begin();
Box box = new Box(); Box box = new Box();
box.setColor( "red-and-white" ); scope.inEntityManager(
em.persist( box ); em -> {
em.close(); box.setColor( "red-and-white" );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); em.persist( box );
}
);
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); transactionManager.commit();
em = scope.getEntityManagerFactory().createEntityManager();
Muffin muffin = new Muffin(); transactionManager.begin();
muffin.setKind( "blueberry" ); scope.inEntityManager(
box.addMuffin( muffin ); em -> {
Muffin muffin = new Muffin();
muffin.setKind( "blueberry" );
box.addMuffin( muffin );
em.merge( box ); em.merge( box );
}
em.close(); );
transactionManager.commit();
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
} }
catch (Exception e) { catch (Exception e) {
final TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager(); rollbackActiveTransaction( transactionManager );
if ( transactionManager.getTransaction() != null && transactionManager.getTransaction()
.getStatus() == Status.STATUS_ACTIVE ) {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
}
throw e; throw e;
} }
finally {
if ( em.isOpen() ) { scope.inEntityManager(
em.close(); em -> {
} final List<Box> boxes = em.createQuery( "from Box" ).getResultList();
} assertThat( boxes.size(), is( 1 ) );
em = scope.getEntityManagerFactory().createEntityManager(); assertThat( boxes.get( 0 ).getMuffinSet().size(), is( 1 ) );
try { }
final List<Box> boxes = em.createQuery( "from Box" ).getResultList(); );
assertThat( boxes.size(), is( 1 ) );
assertThat( boxes.get( 0 ).getMuffinSet().size(), is( 1 ) );
}
finally {
em.close();
}
} }
@Test @Test
@TestForIssue(jiraKey = "HHH-11269") @TestForIssue(jiraKey = "HHH-11269")
public void testMergeWithDeletionOrphanRemovalThenCloseWithAnActiveTransaction(EntityManagerFactoryScope scope) throws Exception { public void testMergeWithDeletionOrphanRemovalThenCloseWithAnActiveTransaction(EntityManagerFactoryScope scope)
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); throws Exception {
EntityManager em = scope.getEntityManagerFactory().createEntityManager(); TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
try { try {
transactionManager.begin();
Muffin muffin = new Muffin(); Muffin muffin = new Muffin();
muffin.setKind( "blueberry" ); muffin.setKind( "blueberry" );
SmallBox box = new SmallBox( muffin ); SmallBox box = new SmallBox( muffin );
box.setColor( "red-and-white" ); box.setColor( "red-and-white" );
em.persist( box ); scope.inEntityManager(
em.close(); em -> em.persist( box )
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); transactionManager.commit();
em = scope.getEntityManagerFactory().createEntityManager();
box.emptyBox(); transactionManager.begin();
scope.inEntityManager(
em -> {
box.emptyBox();
em.merge( box ); em.merge( box );
}
em.close(); );
transactionManager.commit();
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
} }
catch (Exception e) { catch (Exception e) {
final TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager(); rollbackActiveTransaction( transactionManager );
if ( transactionManager.getTransaction() != null && transactionManager.getTransaction()
.getStatus() == Status.STATUS_ACTIVE ) {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
}
throw e; throw e;
} }
finally {
if ( em.isOpen() ) { scope.inEntityManager(
em.close(); em -> {
} final List<SmallBox> boxes = em.createQuery( "from SmallBox" ).getResultList();
} assertThat( boxes.size(), is( 1 ) );
em = scope.getEntityManagerFactory().createEntityManager(); assertTrue( boxes.get( 0 ).isEmpty() );
try { }
final List<SmallBox> boxes = em.createQuery( "from SmallBox" ).getResultList(); );
assertThat( boxes.size(), is( 1 ) );
assertTrue( boxes.get( 0 ).isEmpty() );
}
finally {
em.close();
}
} }
@Test @Test
@TestForIssue(jiraKey = "HHH-11166") @TestForIssue(jiraKey = "HHH-11166")
public void testUpdateThenCloseWithAnActiveTransaction(EntityManagerFactoryScope scope) throws Exception { public void testUpdateThenCloseWithAnActiveTransaction(EntityManagerFactoryScope scope) throws Exception {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
EntityManager em = scope.getEntityManagerFactory().createEntityManager();
try { try {
transactionManager.begin();
Box box = new Box(); Box box = new Box();
box.setColor( "red-and-white" ); scope.inEntityManager(
em.persist( box ); em -> {
em.close(); box.setColor( "red-and-white" );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); em.persist( box );
}
);
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); transactionManager.commit();
em = scope.getEntityManagerFactory().createEntityManager();
box = em.find( Box.class, box.getId() );
Muffin muffin = new Muffin();
muffin.setKind( "blueberry" );
box.addMuffin( muffin );
em.close(); transactionManager.begin();
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); scope.inEntityManager(
em -> {
Box result = em.find( Box.class, box.getId() );
Muffin muffin = new Muffin();
muffin.setKind( "blueberry" );
result.addMuffin( muffin );
}
);
transactionManager.commit();
} }
catch (Exception e) { catch (Exception e) {
final TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager(); rollbackActiveTransaction( transactionManager );
if ( transactionManager.getTransaction() != null && transactionManager.getTransaction()
.getStatus() == Status.STATUS_ACTIVE ) {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
}
throw e; throw e;
} }
finally {
if ( em.isOpen() ) { scope.inEntityManager(
em.close(); em -> {
} final List<Box> boxes = em.createQuery( "from Box" ).getResultList();
} assertThat( boxes.size(), is( 1 ) );
em = scope.getEntityManagerFactory().createEntityManager(); assertThat( boxes.get( 0 ).getMuffinSet().size(), is( 1 ) );
try { }
final List<Box> boxes = em.createQuery( "from Box" ).getResultList(); );
assertThat( boxes.size(), is( 1 ) );
assertThat( boxes.get( 0 ).getMuffinSet().size(), is( 1 ) );
}
finally {
em.close();
}
} }
@Test @Test
@TestForIssue(jiraKey = "HHH-11166") @TestForIssue(jiraKey = "HHH-11166")
public void testRemoveThenCloseWithAnActiveTransaction(EntityManagerFactoryScope scope) throws Exception { public void testRemoveThenCloseWithAnActiveTransaction(EntityManagerFactoryScope scope) throws Exception {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
EntityManager em = scope.getEntityManagerFactory().createEntityManager();
try { try {
transactionManager.begin();
Box box = new Box(); Box box = new Box();
box.setColor( "red-and-white" ); scope.inEntityManager(
em.persist( box ); entityManager -> {
Muffin muffin = new Muffin(); box.setColor( "red-and-white" );
muffin.setKind( "blueberry" ); entityManager.persist( box );
box.addMuffin( muffin ); Muffin muffin = new Muffin();
em.close(); muffin.setKind( "blueberry" );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); box.addMuffin( muffin );
}
);
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); transactionManager.commit();
em = scope.getEntityManagerFactory().createEntityManager();
box = em.find( Box.class, box.getId() );
em.remove( box );
em.close(); transactionManager.begin();
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); scope.inEntityManager(
entityManager -> {
Box result = entityManager.find( Box.class, box.getId() );
entityManager.remove( result );
}
);
transactionManager.commit();
} }
catch (Exception e) { catch (Exception e) {
final TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager(); rollbackActiveTransaction( transactionManager );
if ( transactionManager.getTransaction() != null && transactionManager.getTransaction()
.getStatus() == Status.STATUS_ACTIVE ) {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
}
throw e; throw e;
} }
finally {
if ( em.isOpen() ) { scope.inEntityManager(
em.close(); em -> {
} final List<Box> boxes = em.createQuery( "from Box" ).getResultList();
} assertThat( boxes.size(), is( 0 ) );
em = scope.getEntityManagerFactory().createEntityManager(); }
try { );
final List<Box> boxes = em.createQuery( "from Box" ).getResultList();
assertThat( boxes.size(), is( 0 ) );
}
finally {
em.close();
}
} }
@Test @Test
@TestForIssue(jiraKey = "HHH-11099") @TestForIssue(jiraKey = "HHH-11099")
public void testCommitReleasesLogicalConnection(EntityManagerFactoryScope scope) throws Exception { public void testCommitReleasesLogicalConnection(EntityManagerFactoryScope scope) throws Exception {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
EntityManager em = scope.getEntityManagerFactory().createEntityManager();
try { try {
Box box = new Box(); transactionManager.begin();
box.setColor( "red-and-white" ); final JdbcCoordinatorImpl jdbcCoordinator = scope.fromEntityManager(
em.persist( box ); em -> {
final SessionImpl session = (SessionImpl) em.unwrap( Session.class ); Box box = new Box();
final JdbcCoordinatorImpl jdbcCoordinator = (JdbcCoordinatorImpl) session.getJdbcCoordinator(); box.setColor( "red-and-white" );
em.close(); em.persist( box );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); final SessionImpl session = (SessionImpl) em.unwrap( Session.class );
return (JdbcCoordinatorImpl) session.getJdbcCoordinator();
}
);
transactionManager.commit();
assertThat( assertThat(
"The logical connection is still open after commit", "The logical connection is still open after commit",
jdbcCoordinator.getLogicalConnection().isOpen(), jdbcCoordinator.getLogicalConnection().isOpen(),
@ -332,18 +304,22 @@ public class CloseEntityManagerWithActiveTransactionTest {
); );
} }
catch (Exception e) { catch (Exception e) {
final TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager(); rollbackActiveTransaction( transactionManager );
if ( transactionManager.getTransaction() != null && transactionManager.getTransaction()
.getStatus() == Status.STATUS_ACTIVE ) {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
}
throw e; throw e;
} }
finally { }
if ( em.isOpen() ) {
em.close(); private void rollbackActiveTransaction(TransactionManager transactionManager) {
try {
switch ( transactionManager.getStatus() ) {
case Status.STATUS_ACTIVE:
case Status.STATUS_MARKED_ROLLBACK:
transactionManager.rollback();
} }
} }
catch (Exception exception) {
//ignore exception
}
} }
@Entity(name = "Container") @Entity(name = "Container")

View File

@ -30,8 +30,8 @@ public class GetTransactionTest {
EntityTransaction t = entityManager.getTransaction(); EntityTransaction t = entityManager.getTransaction();
assertSame( t, entityManager.getTransaction() ); assertSame( t, entityManager.getTransaction() );
assertFalse( t.isActive() ); assertFalse( t.isActive() );
t.begin();
try { try {
t.begin();
assertSame( t, entityManager.getTransaction() ); assertSame( t, entityManager.getTransaction() );
assertTrue( t.isActive() ); assertTrue( t.isActive() );
t.commit(); t.commit();

View File

@ -12,10 +12,12 @@ import javax.persistence.SynchronizationType;
import javax.persistence.TransactionRequiredException; import javax.persistence.TransactionRequiredException;
import javax.persistence.criteria.CriteriaDelete; import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.CriteriaUpdate; import javax.persistence.criteria.CriteriaUpdate;
import javax.transaction.Status;
import javax.transaction.TransactionManager;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper; import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.jpa.test.transaction.Book; import org.hibernate.jpa.test.transaction.Book;
import org.hibernate.jpa.test.transaction.Book_; import org.hibernate.jpa.test.transaction.Book_;
import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl; import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl;
@ -75,21 +77,23 @@ public class SynchronizationTypeTest {
public void testImplicitJoining(EntityManagerFactoryScope scope) throws Exception { public void testImplicitJoining(EntityManagerFactoryScope scope) throws Exception {
// here the transaction is started before the EM is opened. Because the SynchronizationType is UNSYNCHRONIZED // here the transaction is started before the EM is opened. Because the SynchronizationType is UNSYNCHRONIZED
// though, it should not auto join the transaction // though, it should not auto join the transaction
EntityManager entityManager = null;
TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
assertFalse( assertFalse(
JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ), JtaStatusHelper.isActive( transactionManager ),
"setup problem" "setup problem"
); );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
assertTrue(
JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ),
"setup problem"
);
EntityManager entityManager = scope.getEntityManagerFactory()
.createEntityManager( SynchronizationType.UNSYNCHRONIZED, null );
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
try { try {
transactionManager.begin();
assertTrue(
JtaStatusHelper.isActive( transactionManager ),
"setup problem"
);
entityManager = scope.getEntityManagerFactory()
.createEntityManager( SynchronizationType.UNSYNCHRONIZED, null );
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() ); ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator(); JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator();
@ -104,7 +108,7 @@ public class SynchronizationTypeTest {
assertFalse( transactionCoordinator.isJoined() ); assertFalse( transactionCoordinator.isJoined() );
entityManager.joinTransaction(); entityManager.joinTransaction();
assertTrue( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) ); assertTrue( JtaStatusHelper.isActive( transactionManager ) );
assertTrue( transactionCoordinator.isActive() ); assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isSynchronizationRegistered() ); assertTrue( transactionCoordinator.isSynchronizationRegistered() );
assertTrue( transactionCoordinator.isActive() ); assertTrue( transactionCoordinator.isActive() );
@ -116,12 +120,24 @@ public class SynchronizationTypeTest {
assertFalse( entityManager.isOpen() ); assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() ); assertFalse( session.isOpen() );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); transactionManager.commit();
assertFalse( entityManager.isOpen() ); assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() ); assertFalse( session.isOpen() );
} }
catch (Throwable t) {
try {
switch ( transactionManager.getStatus() ) {
case Status.STATUS_ACTIVE:
case Status.STATUS_MARKED_ROLLBACK:
transactionManager.rollback();
}
}
catch (Exception exception) {
//ignore exception
}
}
finally { finally {
if ( entityManager.isOpen() ) { if ( entityManager != null && entityManager.isOpen() ) {
entityManager.close(); entityManager.close();
} }
} }
@ -133,23 +149,24 @@ public class SynchronizationTypeTest {
public void testDisallowedOperations(EntityManagerFactoryScope scope) throws Exception { public void testDisallowedOperations(EntityManagerFactoryScope scope) throws Exception {
// test calling operations that are disallowed while a UNSYNCHRONIZED persistence context is not // test calling operations that are disallowed while a UNSYNCHRONIZED persistence context is not
// yet joined/enlisted // yet joined/enlisted
EntityManager entityManager = null;
TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
assertFalse( assertFalse(
JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ), JtaStatusHelper.isActive( transactionManager ),
"setup problem" "setup problem"
); );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
assertTrue(
JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ),
"setup problem"
);
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager(
SynchronizationType.UNSYNCHRONIZED,
null
);
try { try {
transactionManager.begin();
assertTrue(
JtaStatusHelper.isActive( transactionManager ),
"setup problem"
);
entityManager = scope.getEntityManagerFactory().createEntityManager(
SynchronizationType.UNSYNCHRONIZED,
null
);
// explicit flushing // explicit flushing
try { try {
entityManager.flush(); entityManager.flush();
@ -202,13 +219,12 @@ public class SynchronizationTypeTest {
} }
catch (TransactionRequiredException expected) { catch (TransactionRequiredException expected) {
} }
} }
finally { finally {
if ( entityManager.isOpen() ) { if ( entityManager != null && entityManager.isOpen() ) {
entityManager.close(); entityManager.close();
} }
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback(); transactionManager.rollback();
} }
} }
} }

View File

@ -98,6 +98,9 @@ public class TransactionCommitFailureTest {
//expected //expected
} }
finally { finally {
if ( em.getTransaction() != null && em.getTransaction().isActive() ) {
em.getTransaction().rollback();
}
em.close(); em.close();
} }

View File

@ -7,6 +7,8 @@
package org.hibernate.orm.test.jpa.transaction; package org.hibernate.orm.test.jpa.transaction;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.transaction.Status;
import javax.transaction.TransactionManager;
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper; import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
import org.hibernate.internal.SessionImpl; import org.hibernate.internal.SessionImpl;
@ -26,6 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
*/ */
public class TransactionJoinHandlingChecker { public class TransactionJoinHandlingChecker {
public static void validateExplicitJoiningHandling(EntityManager entityManager) throws Exception { public static void validateExplicitJoiningHandling(EntityManager entityManager) throws Exception {
TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
try (SessionImpl session = entityManager.unwrap( SessionImpl.class )) { try (SessionImpl session = entityManager.unwrap( SessionImpl.class )) {
@ -41,20 +44,20 @@ public class TransactionJoinHandlingChecker {
assertFalse( transactionCoordinator.isJtaTransactionCurrentlyActive() ); assertFalse( transactionCoordinator.isJtaTransactionCurrentlyActive() );
assertFalse( transactionCoordinator.isJoined() ); assertFalse( transactionCoordinator.isJoined() );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); transactionManager.begin();
assertTrue( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) ); assertTrue( JtaStatusHelper.isActive( transactionManager ) );
assertTrue( transactionCoordinator.isJtaTransactionCurrentlyActive() ); assertTrue( transactionCoordinator.isJtaTransactionCurrentlyActive() );
assertFalse( transactionCoordinator.isJoined() ); assertFalse( transactionCoordinator.isJoined() );
assertFalse( transactionCoordinator.isSynchronizationRegistered() ); assertFalse( transactionCoordinator.isSynchronizationRegistered() );
session.getFlushMode(); session.getFlushMode();
assertTrue( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) ); assertTrue( JtaStatusHelper.isActive( transactionManager ) );
assertTrue( transactionCoordinator.isJtaTransactionCurrentlyActive() ); assertTrue( transactionCoordinator.isJtaTransactionCurrentlyActive() );
assertFalse( transactionCoordinator.isJoined() ); assertFalse( transactionCoordinator.isJoined() );
assertFalse( transactionCoordinator.isSynchronizationRegistered() ); assertFalse( transactionCoordinator.isSynchronizationRegistered() );
entityManager.joinTransaction(); entityManager.joinTransaction();
assertTrue( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) ); assertTrue( JtaStatusHelper.isActive( transactionManager ) );
assertTrue( transactionCoordinator.isJtaTransactionCurrentlyActive() ); assertTrue( transactionCoordinator.isJtaTransactionCurrentlyActive() );
assertTrue( transactionCoordinator.isSynchronizationRegistered() ); assertTrue( transactionCoordinator.isSynchronizationRegistered() );
assertTrue( transactionCoordinator.isJoined() ); assertTrue( transactionCoordinator.isJoined() );
@ -65,9 +68,22 @@ public class TransactionJoinHandlingChecker {
assertFalse( entityManager.isOpen() ); assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() ); assertFalse( session.isOpen() );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); transactionManager.commit();
assertFalse( entityManager.isOpen() ); assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() ); assertFalse( session.isOpen() );
} }
catch (Throwable t){
try {
switch ( transactionManager.getStatus() ) {
case Status.STATUS_ACTIVE:
case Status.STATUS_MARKED_ROLLBACK:
transactionManager.rollback();
}
}
catch (Exception exception) {
//ignore exception
}
throw t;
}
} }
} }

View File

@ -12,6 +12,7 @@ import javax.persistence.PersistenceException;
import javax.persistence.SynchronizationType; import javax.persistence.SynchronizationType;
import javax.persistence.TransactionRequiredException; import javax.persistence.TransactionRequiredException;
import javax.transaction.Status; import javax.transaction.Status;
import javax.transaction.TransactionManager;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
@ -22,13 +23,12 @@ import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoo
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.jta.TestingJtaPlatformImpl; import org.hibernate.testing.jta.TestingJtaPlatformImpl;
import org.hibernate.testing.orm.junit.ExtraAssertions;
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
import org.hibernate.testing.orm.junit.ExtraAssertions;
import org.hibernate.testing.orm.junit.Jpa; import org.hibernate.testing.orm.junit.Jpa;
import org.hibernate.testing.orm.junit.Setting; import org.hibernate.testing.orm.junit.Setting;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
@ -70,7 +70,10 @@ public class TransactionJoiningTest {
// a TransactionRequiredException to be thrown // a TransactionRequiredException to be thrown
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager(); EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager();
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ), "setup problem" ); assertFalse(
JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ),
"setup problem"
);
try { try {
Assertions.assertThrows( Assertions.assertThrows(
@ -88,125 +91,134 @@ public class TransactionJoiningTest {
public void testImplicitJoining(EntityManagerFactoryScope scope) throws Exception { public void testImplicitJoining(EntityManagerFactoryScope scope) throws Exception {
// here the transaction is started before the EM is opened... // here the transaction is started before the EM is opened...
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) ); EntityManager entityManager = null;
TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
assertFalse( JtaStatusHelper.isActive( transactionManager ) );
try {
transactionManager.begin();
entityManager = scope.getEntityManagerFactory().createEntityManager();
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager(); JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator();
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() ); assertTrue( transactionCoordinator.isSynchronizationRegistered() );
JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator(); assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
assertTrue( transactionCoordinator.isSynchronizationRegistered() ); assertTrue( entityManager.isOpen() );
assertTrue( transactionCoordinator.isActive() ); assertTrue( session.isOpen() );
assertTrue( transactionCoordinator.isJoined() ); entityManager.close();
assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() );
assertTrue( entityManager.isOpen() ); transactionManager.commit();
assertTrue( session.isOpen() ); assertFalse( entityManager.isOpen() );
entityManager.close(); assertFalse( session.isOpen() );
assertFalse( entityManager.isOpen() ); }
assertFalse( session.isOpen() ); finally {
rollbackActiveTransacionrAndCloseEntityManager( entityManager, transactionManager );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); }
assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() );
} }
@Test @Test
@TestForIssue(jiraKey = "HHH-10807") @TestForIssue(jiraKey = "HHH-10807")
public void testIsJoinedAfterMarkedForRollbackImplicit(EntityManagerFactoryScope scope) throws Exception { public void testIsJoinedAfterMarkedForRollbackImplicit(EntityManagerFactoryScope scope) throws Exception {
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) ); EntityManager entityManager = null;
TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); assertFalse( JtaStatusHelper.isActive( transactionManager ) );
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager();
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator();
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
assertTrue( entityManager.isOpen() );
assertTrue( session.isOpen() );
transactionCoordinator.getTransactionDriverControl().markRollbackOnly();
assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
assertTrue( entityManager.isJoinedToTransaction() );
try { try {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback(); transactionManager.begin();
entityManager = scope.getEntityManagerFactory().createEntityManager();
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator();
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
assertTrue( entityManager.isOpen() );
assertTrue( session.isOpen() );
transactionCoordinator.getTransactionDriverControl().markRollbackOnly();
assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
assertTrue( entityManager.isJoinedToTransaction() );
transactionManager.rollback();
entityManager.close(); entityManager.close();
assertFalse( entityManager.isOpen() ); assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() ); assertFalse( session.isOpen() );
} }
finally { finally {
// ensure the entityManager is closed in case the rollback call fails rollbackActiveTransacionrAndCloseEntityManager( entityManager, transactionManager );
entityManager.close();
} }
} }
@Test @Test
@TestForIssue(jiraKey = "HHH-10807") @TestForIssue(jiraKey = "HHH-10807")
public void testIsJoinedAfterMarkedForRollbackExplicit(EntityManagerFactoryScope scope) throws Exception { public void testIsJoinedAfterMarkedForRollbackExplicit(EntityManagerFactoryScope scope) throws Exception {
EntityManager entityManager = null;
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) ); TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
assertFalse( JtaStatusHelper.isActive( transactionManager ) );
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager( SynchronizationType.UNSYNCHRONIZED );
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
assertTrue( entityManager.isOpen() );
assertTrue( session.isOpen() );
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator();
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
entityManager.joinTransaction();
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
transactionCoordinator.getTransactionDriverControl().markRollbackOnly();
assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
assertTrue( entityManager.isJoinedToTransaction() );
try { try {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback(); entityManager = scope.getEntityManagerFactory()
.createEntityManager( SynchronizationType.UNSYNCHRONIZED );
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
assertTrue( entityManager.isOpen() );
assertTrue( session.isOpen() );
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator();
transactionManager.begin();
entityManager.joinTransaction();
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
transactionCoordinator.getTransactionDriverControl().markRollbackOnly();
assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
assertTrue( entityManager.isJoinedToTransaction() );
transactionManager.rollback();
entityManager.close(); entityManager.close();
assertFalse( entityManager.isOpen() ); assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() ); assertFalse( session.isOpen() );
} }
finally { finally {
// ensure the entityManager is closed in case the rollback call fails rollbackActiveTransacionrAndCloseEntityManager( entityManager, transactionManager );
entityManager.close();
} }
} }
@Test @Test
public void testCloseAfterCommit(EntityManagerFactoryScope scope) throws Exception { public void testCloseAfterCommit(EntityManagerFactoryScope scope) throws Exception {
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) ); EntityManager entityManager = null;
TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); assertFalse( JtaStatusHelper.isActive( transactionManager ) );
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager();
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator();
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
assertTrue( entityManager.isOpen() );
assertTrue( session.isOpen() );
try { try {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); transactionManager.begin();
entityManager = scope.getEntityManagerFactory().createEntityManager();
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator();
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
assertTrue( entityManager.isOpen() );
assertTrue( session.isOpen() );
transactionManager.commit();
assertTrue( entityManager.isOpen() ); assertTrue( entityManager.isOpen() );
assertTrue( session.isOpen() ); assertTrue( session.isOpen() );
@ -215,29 +227,34 @@ public class TransactionJoiningTest {
assertFalse( session.isOpen() ); assertFalse( session.isOpen() );
} }
finally { finally {
// ensure the entityManager is closed in case the commit call fails rollbackActiveTransacionrAndCloseEntityManager( entityManager, transactionManager );
entityManager.close();
} }
} }
@Test @Test
public void testImplicitJoiningWithExtraSynchronization(EntityManagerFactoryScope scope) throws Exception { public void testImplicitJoiningWithExtraSynchronization(EntityManagerFactoryScope scope) throws Exception {
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) ); EntityManager entityManager = null;
TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
assertFalse( JtaStatusHelper.isActive( transactionManager ) );
try {
transactionManager.begin();
entityManager = scope.getEntityManagerFactory().createEntityManager();
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager(); JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator();
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() ); assertTrue( transactionCoordinator.isSynchronizationRegistered() );
JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator(); assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
assertTrue( transactionCoordinator.isSynchronizationRegistered() ); entityManager.close();
assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
entityManager.close(); transactionManager.commit();
}
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); finally {
rollbackActiveTransacionrAndCloseEntityManager( entityManager, transactionManager );
}
} }
/** /**
@ -251,10 +268,13 @@ public class TransactionJoiningTest {
@Test @Test
@TestForIssue(jiraKey = "HHH-7910") @TestForIssue(jiraKey = "HHH-7910")
public void testMultiThreadTransactionTimeout(EntityManagerFactoryScope scope) throws Exception { public void testMultiThreadTransactionTimeout(EntityManagerFactoryScope scope) throws Exception {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); EntityManager em = null;
TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
EntityManager em = scope.getEntityManagerFactory().createEntityManager();
try { try {
transactionManager.begin();
em = scope.getEntityManagerFactory().createEntityManager();
final SessionImpl sImpl = em.unwrap( SessionImpl.class ); final SessionImpl sImpl = em.unwrap( SessionImpl.class );
final CountDownLatch latch = new CountDownLatch( 1 ); final CountDownLatch latch = new CountDownLatch( 1 );
@ -291,9 +311,28 @@ public class TransactionJoiningTest {
} }
assertTrue( caught ); assertTrue( caught );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback(); transactionManager.rollback();
} }
finally { finally {
rollbackActiveTransacionrAndCloseEntityManager( em, transactionManager );
}
}
private void rollbackActiveTransacionrAndCloseEntityManager(
EntityManager em,
TransactionManager transactionManager) {
try {
switch ( transactionManager.getStatus() ) {
case Status.STATUS_ACTIVE:
case Status.STATUS_MARKED_ROLLBACK:
transactionManager.rollback();
}
}
catch (Exception exception) {
//ignore exception
}
// ensure the entityManager is closed in case the rollback call fails
if ( em != null && em.isOpen() ) {
em.close(); em.close();
} }
} }

View File

@ -50,41 +50,48 @@ public class TransactionRollbackTest {
final Session session = entityManager.unwrap( Session.class ); final Session session = entityManager.unwrap( Session.class );
final OperationCollectorObserver transactionObserver = new OperationCollectorObserver(); final OperationCollectorObserver transactionObserver = new OperationCollectorObserver();
( (JdbcSessionOwner) session ).getTransactionCoordinator().addObserver( transactionObserver ); ( (JdbcSessionOwner) session ).getTransactionCoordinator().addObserver( transactionObserver );
entityManager.getTransaction().begin(); try {
entityManager.getTransaction().begin();
// given two inserted records // given two inserted records
entityManager.persist( new Shipment( "shipment-1", "INITIAL" ) ); entityManager.persist( new Shipment( "shipment-1", "INITIAL" ) );
entityManager.persist( new Shipment( "shipment-2", "INITIAL" ) ); entityManager.persist( new Shipment( "shipment-2", "INITIAL" ) );
entityManager.flush(); entityManager.flush();
entityManager.clear(); entityManager.clear();
Assertions.assertThrows( Assertions.assertThrows(
Exception.class, Exception.class,
() -> { () -> {
// when provoking a duplicate-key exception // when provoking a duplicate-key exception
entityManager.persist( new Shipment( "shipment-1", "INITIAL" ) ); entityManager.persist( new Shipment( "shipment-1", "INITIAL" ) );
entityManager.getTransaction().commit(); entityManager.getTransaction().commit();
}, },
"Expected exception was not raised" "Expected exception was not raised"
); );
assertThat( transactionObserver.getUnSuccessfulAfterCompletion(), is( 1 ) ); assertThat( transactionObserver.getUnSuccessfulAfterCompletion(), is( 1 ) );
entityManager.clear(); entityManager.clear();
entityManager.getTransaction().begin(); entityManager.getTransaction().begin();
Shipment shipment = entityManager.find( Shipment.class, "shipment-1" ); Shipment shipment = entityManager.find( Shipment.class, "shipment-1" );
if ( shipment != null ) { if ( shipment != null ) {
entityManager.remove( shipment ); entityManager.remove( shipment );
}
shipment = entityManager.find( Shipment.class, "shipment-2" );
if ( shipment != null ) {
entityManager.remove( shipment );
}
entityManager.getTransaction().commit();
} }
catch (Throwable t) {
shipment = entityManager.find( Shipment.class, "shipment-2" ); if ( entityManager.getTransaction().isActive() ) {
if ( shipment != null ) { entityManager.getTransaction().rollback();
entityManager.remove( shipment ); }
} }
entityManager.getTransaction().commit();
} }
); );
} }

View File

@ -10,15 +10,15 @@ import javax.persistence.EntityManager;
import javax.transaction.RollbackException; import javax.transaction.RollbackException;
import javax.transaction.Status; import javax.transaction.Status;
import javax.transaction.SystemException; import javax.transaction.SystemException;
import javax.transaction.TransactionManager;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.junit.jupiter.api.Test;
import org.hibernate.testing.jta.TestingJtaPlatformImpl; import org.hibernate.testing.jta.TestingJtaPlatformImpl;
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
import org.hibernate.testing.orm.junit.Jpa; import org.hibernate.testing.orm.junit.Jpa;
import org.hibernate.testing.orm.junit.Setting; import org.hibernate.testing.orm.junit.Setting;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
@ -49,12 +49,14 @@ public class TransactionRolledBackInDifferentThreadTest {
*/ */
// main test thread // main test thread
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
final EntityManager em = scope.getEntityManagerFactory().createEntityManager();
em.joinTransaction();
TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
transactionManager.begin();
final EntityManager em = scope.getEntityManagerFactory().createEntityManager();
try { try {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); em.joinTransaction();
transactionManager.commit();
// will be set to the failing exception // will be set to the failing exception
final HibernateException[] transactionRolledBackInDifferentThreadException = new HibernateException[2]; final HibernateException[] transactionRolledBackInDifferentThreadException = new HibernateException[2];
@ -63,10 +65,10 @@ public class TransactionRolledBackInDifferentThreadTest {
// background test thread 1 // background test thread 1
final Runnable run1 = () -> { final Runnable run1 = () -> {
try { try {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); transactionManager.begin();
em.joinTransaction(); em.joinTransaction();
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().setRollbackOnly(); transactionManager.setRollbackOnly();
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); transactionManager.commit();
} }
catch (javax.persistence.PersistenceException e) { catch (javax.persistence.PersistenceException e) {
if ( e.getCause() instanceof HibernateException && if ( e.getCause() instanceof HibernateException &&
@ -86,9 +88,9 @@ public class TransactionRolledBackInDifferentThreadTest {
} }
finally { finally {
try { try {
if ( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() if ( transactionManager
.getStatus() != Status.STATUS_NO_TRANSACTION ) { .getStatus() != Status.STATUS_NO_TRANSACTION ) {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback(); transactionManager.rollback();
} }
} }
catch (SystemException ignore) { catch (SystemException ignore) {
@ -99,13 +101,13 @@ public class TransactionRolledBackInDifferentThreadTest {
// test thread 2 // test thread 2
final Runnable run2 = () -> { final Runnable run2 = () -> {
try { try {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin(); transactionManager.begin();
/* /*
* the following call to em.joinTransaction() will throw: * the following call to em.joinTransaction() will throw:
* org.hibernate.HibernateException: Transaction was rolled back in a different thread! * org.hibernate.HibernateException: Transaction was rolled back in a different thread!
*/ */
em.joinTransaction(); em.joinTransaction();
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit(); transactionManager.commit();
} }
catch (javax.persistence.PersistenceException e) { catch (javax.persistence.PersistenceException e) {
if ( e.getCause() instanceof HibernateException && if ( e.getCause() instanceof HibernateException &&
@ -122,9 +124,9 @@ public class TransactionRolledBackInDifferentThreadTest {
} }
finally { finally {
try { try {
if ( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() if ( transactionManager
.getStatus() != Status.STATUS_NO_TRANSACTION ) { .getStatus() != Status.STATUS_NO_TRANSACTION ) {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback(); transactionManager.rollback();
} }
} }
catch (SystemException ignore) { catch (SystemException ignore) {
@ -142,8 +144,7 @@ public class TransactionRolledBackInDifferentThreadTest {
// show failure for exception caught in run2.run() // show failure for exception caught in run2.run()
if ( transactionRolledBackInDifferentThreadException[0] != null if ( transactionRolledBackInDifferentThreadException[0] != null
|| transactionRolledBackInDifferentThreadException[1] != null ) || transactionRolledBackInDifferentThreadException[1] != null ) {
{
fail( fail(
"failure in test thread 1 = " + "failure in test thread 1 = " +
( transactionRolledBackInDifferentThreadException[0] != null ? ( transactionRolledBackInDifferentThreadException[0] != null ?
@ -157,6 +158,16 @@ public class TransactionRolledBackInDifferentThreadTest {
} }
} }
finally { finally {
try {
switch ( transactionManager.getStatus() ) {
case Status.STATUS_ACTIVE:
case Status.STATUS_MARKED_ROLLBACK:
transactionManager.rollback();
}
}
catch (Exception exception) {
//ignore exception
}
em.close(); em.close();
} }
} }

View File

@ -38,6 +38,7 @@ import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not; import static org.hamcrest.core.IsNot.not;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.fail;
/** /**
* @author Gail Badner * @author Gail Badner
@ -91,6 +92,7 @@ public class JtaWithFailingBatchTest extends AbstractJtaBatchTest {
em.persist( comment ); em.persist( comment );
transactionManager.commit(); transactionManager.commit();
fail("An Exception is expected");
} }
catch (Exception expected) { catch (Exception expected) {
//expected //expected

View File

@ -92,16 +92,18 @@ public class JtaWithStatementsBatchTest extends AbstractJtaBatchTest {
assertStatementsListIsCleared(); assertStatementsListIsCleared();
assertAllStatementsAreClosed( testBatch.createdStatements ); assertAllStatementsAreClosed( testBatch.createdStatements );
} }
catch (Exception e) { catch (Throwable t) {
try { try {
switch ( transactionManager.getStatus() ) { switch ( transactionManager.getStatus() ) {
case Status.STATUS_ACTIVE: case Status.STATUS_ACTIVE:
case Status.STATUS_MARKED_ROLLBACK: case Status.STATUS_MARKED_ROLLBACK:
transactionManager.rollback(); transactionManager.rollback();
} }
}catch (Exception e2){ }
catch (Exception e) {
//ignore e //ignore e
} }
throw new RuntimeException( t );
} }
assertFalse( assertFalse(