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

View File

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

View File

@ -12,10 +12,12 @@ import javax.persistence.SynchronizationType;
import javax.persistence.TransactionRequiredException;
import javax.persistence.criteria.CriteriaDelete;
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.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.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl;
@ -75,21 +77,23 @@ public class SynchronizationTypeTest {
public void testImplicitJoining(EntityManagerFactoryScope scope) throws Exception {
// here the transaction is started before the EM is opened. Because the SynchronizationType is UNSYNCHRONIZED
// though, it should not auto join the transaction
EntityManager entityManager = null;
TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
assertFalse(
JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ),
JtaStatusHelper.isActive( transactionManager ),
"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 {
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() );
JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator();
@ -104,7 +108,7 @@ public class SynchronizationTypeTest {
assertFalse( transactionCoordinator.isJoined() );
entityManager.joinTransaction();
assertTrue( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
assertTrue( JtaStatusHelper.isActive( transactionManager ) );
assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
assertTrue( transactionCoordinator.isActive() );
@ -116,12 +120,24 @@ public class SynchronizationTypeTest {
assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
transactionManager.commit();
assertFalse( entityManager.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 {
if ( entityManager.isOpen() ) {
if ( entityManager != null && entityManager.isOpen() ) {
entityManager.close();
}
}
@ -133,23 +149,24 @@ public class SynchronizationTypeTest {
public void testDisallowedOperations(EntityManagerFactoryScope scope) throws Exception {
// test calling operations that are disallowed while a UNSYNCHRONIZED persistence context is not
// yet joined/enlisted
EntityManager entityManager = null;
TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
assertFalse(
JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ),
JtaStatusHelper.isActive( transactionManager ),
"setup problem"
);
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
assertTrue(
JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ),
"setup problem"
);
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager(
SynchronizationType.UNSYNCHRONIZED,
null
);
try {
transactionManager.begin();
assertTrue(
JtaStatusHelper.isActive( transactionManager ),
"setup problem"
);
entityManager = scope.getEntityManagerFactory().createEntityManager(
SynchronizationType.UNSYNCHRONIZED,
null
);
// explicit flushing
try {
entityManager.flush();
@ -202,13 +219,12 @@ public class SynchronizationTypeTest {
}
catch (TransactionRequiredException expected) {
}
}
finally {
if ( entityManager.isOpen() ) {
if ( entityManager != null && entityManager.isOpen() ) {
entityManager.close();
}
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
transactionManager.rollback();
}
}
}

View File

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

View File

@ -7,6 +7,8 @@
package org.hibernate.orm.test.jpa.transaction;
import javax.persistence.EntityManager;
import javax.transaction.Status;
import javax.transaction.TransactionManager;
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
import org.hibernate.internal.SessionImpl;
@ -26,6 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
*/
public class TransactionJoinHandlingChecker {
public static void validateExplicitJoiningHandling(EntityManager entityManager) throws Exception {
TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
try (SessionImpl session = entityManager.unwrap( SessionImpl.class )) {
@ -41,20 +44,20 @@ public class TransactionJoinHandlingChecker {
assertFalse( transactionCoordinator.isJtaTransactionCurrentlyActive() );
assertFalse( transactionCoordinator.isJoined() );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
assertTrue( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
transactionManager.begin();
assertTrue( JtaStatusHelper.isActive( transactionManager ) );
assertTrue( transactionCoordinator.isJtaTransactionCurrentlyActive() );
assertFalse( transactionCoordinator.isJoined() );
assertFalse( transactionCoordinator.isSynchronizationRegistered() );
session.getFlushMode();
assertTrue( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
assertTrue( JtaStatusHelper.isActive( transactionManager ) );
assertTrue( transactionCoordinator.isJtaTransactionCurrentlyActive() );
assertFalse( transactionCoordinator.isJoined() );
assertFalse( transactionCoordinator.isSynchronizationRegistered() );
entityManager.joinTransaction();
assertTrue( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
assertTrue( JtaStatusHelper.isActive( transactionManager ) );
assertTrue( transactionCoordinator.isJtaTransactionCurrentlyActive() );
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
assertTrue( transactionCoordinator.isJoined() );
@ -65,9 +68,22 @@ public class TransactionJoinHandlingChecker {
assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
transactionManager.commit();
assertFalse( entityManager.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.TransactionRequiredException;
import javax.transaction.Status;
import javax.transaction.TransactionManager;
import org.hibernate.HibernateException;
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.jta.TestingJtaPlatformImpl;
import org.hibernate.testing.orm.junit.ExtraAssertions;
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.Setting;
import org.junit.jupiter.api.Test;
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.assertTrue;
@ -70,7 +70,10 @@ public class TransactionJoiningTest {
// a TransactionRequiredException to be thrown
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager();
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ), "setup problem" );
assertFalse(
JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ),
"setup problem"
);
try {
Assertions.assertThrows(
@ -88,125 +91,134 @@ public class TransactionJoiningTest {
public void testImplicitJoining(EntityManagerFactoryScope scope) throws Exception {
// 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();
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager();
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator();
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator();
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
assertTrue( entityManager.isOpen() );
assertTrue( session.isOpen() );
entityManager.close();
assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() );
assertTrue( entityManager.isOpen() );
assertTrue( session.isOpen() );
entityManager.close();
assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() );
transactionManager.commit();
assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() );
}
finally {
rollbackActiveTransacionrAndCloseEntityManager( entityManager, transactionManager );
}
}
@Test
@TestForIssue(jiraKey = "HHH-10807")
public void testIsJoinedAfterMarkedForRollbackImplicit(EntityManagerFactoryScope scope) throws Exception {
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
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() );
EntityManager entityManager = null;
TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
assertFalse( JtaStatusHelper.isActive( transactionManager ) );
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();
assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() );
}
finally {
// ensure the entityManager is closed in case the rollback call fails
entityManager.close();
rollbackActiveTransacionrAndCloseEntityManager( entityManager, transactionManager );
}
}
@Test
@TestForIssue(jiraKey = "HHH-10807")
public void testIsJoinedAfterMarkedForRollbackExplicit(EntityManagerFactoryScope scope) throws Exception {
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
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() );
EntityManager entityManager = null;
TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
assertFalse( JtaStatusHelper.isActive( transactionManager ) );
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();
assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() );
}
finally {
// ensure the entityManager is closed in case the rollback call fails
entityManager.close();
rollbackActiveTransacionrAndCloseEntityManager( entityManager, transactionManager );
}
}
@Test
public void testCloseAfterCommit(EntityManagerFactoryScope scope) throws Exception {
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
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() );
EntityManager entityManager = null;
TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
assertFalse( JtaStatusHelper.isActive( transactionManager ) );
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( session.isOpen() );
@ -215,29 +227,34 @@ public class TransactionJoiningTest {
assertFalse( session.isOpen() );
}
finally {
// ensure the entityManager is closed in case the commit call fails
entityManager.close();
rollbackActiveTransacionrAndCloseEntityManager( entityManager, transactionManager );
}
}
@Test
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();
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager();
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator();
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator();
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
assertTrue( transactionCoordinator.isSynchronizationRegistered() );
assertTrue( transactionCoordinator.isActive() );
assertTrue( transactionCoordinator.isJoined() );
entityManager.close();
entityManager.close();
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
transactionManager.commit();
}
finally {
rollbackActiveTransacionrAndCloseEntityManager( entityManager, transactionManager );
}
}
/**
@ -251,10 +268,13 @@ public class TransactionJoiningTest {
@Test
@TestForIssue(jiraKey = "HHH-7910")
public void testMultiThreadTransactionTimeout(EntityManagerFactoryScope scope) throws Exception {
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
EntityManager em = scope.getEntityManagerFactory().createEntityManager();
EntityManager em = null;
TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
try {
transactionManager.begin();
em = scope.getEntityManagerFactory().createEntityManager();
final SessionImpl sImpl = em.unwrap( SessionImpl.class );
final CountDownLatch latch = new CountDownLatch( 1 );
@ -291,9 +311,28 @@ public class TransactionJoiningTest {
}
assertTrue( caught );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
transactionManager.rollback();
}
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();
}
}

View File

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

View File

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

View File

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