HHH-14503 - Migration of tests from jpa/test to orm/test/jpa
Signed-off-by: Jan Schatteman <jschatte@redhat.com>
This commit is contained in:
parent
9bbad43e75
commit
4a59e2d002
|
@ -1,85 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.jpa.test.transaction;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.EntityTransaction;
|
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
|
|
||||||
import org.hibernate.orm.test.jpa.transaction.SynchronizationTypeTest;
|
|
||||||
|
|
||||||
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.hamcrest.MatcherAssert.assertThat;
|
|
||||||
import static org.hamcrest.core.Is.is;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Andrea Boriero
|
|
||||||
*/
|
|
||||||
@Jpa(
|
|
||||||
annotatedClasses = { JtaReusingEntityTransactionTest.TestEntity.class },
|
|
||||||
integrationSettings = {
|
|
||||||
@Setting(name = org.hibernate.jpa.AvailableSettings.TRANSACTION_TYPE, value = "JTA"),
|
|
||||||
@Setting(name = org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER, value = "org.hibernate.testing.jta.JtaAwareConnectionProviderImpl"),
|
|
||||||
|
|
||||||
},
|
|
||||||
nonStringValueSettingProviders = { SynchronizationTypeTest.JtaPlatformNonStringValueSettingProvider.class }
|
|
||||||
)
|
|
||||||
public class JtaReusingEntityTransactionTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void entityTransactionShouldBeReusableTest(EntityManagerFactoryScope scope) {
|
|
||||||
EntityManager em = createEntityManager( scope );
|
|
||||||
EntityTransaction transaction = null;
|
|
||||||
try {
|
|
||||||
transaction = em.getTransaction();
|
|
||||||
em.persist( new TestEntity() );
|
|
||||||
transaction.begin();
|
|
||||||
transaction.commit();
|
|
||||||
transaction.begin();
|
|
||||||
em.persist( new TestEntity() );
|
|
||||||
transaction.commit();
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if ( transaction != null && transaction.isActive() ) {
|
|
||||||
transaction.rollback();
|
|
||||||
}
|
|
||||||
em.close();
|
|
||||||
}
|
|
||||||
em = createEntityManager( scope );
|
|
||||||
try {
|
|
||||||
transaction = em.getTransaction();
|
|
||||||
transaction.begin();
|
|
||||||
List<TestEntity> results = em.createQuery( "from TestEntity" ).getResultList();
|
|
||||||
assertThat( results.size(), is( 2 ) );
|
|
||||||
transaction.commit();
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if ( transaction != null && transaction.isActive() ) {
|
|
||||||
transaction.rollback();
|
|
||||||
}
|
|
||||||
em.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private EntityManager createEntityManager(EntityManagerFactoryScope scope) {
|
|
||||||
return scope.getEntityManagerFactory().createEntityManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Entity(name = "TestEntity")
|
|
||||||
public static class TestEntity {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue
|
|
||||||
private Long id;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,158 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.jpa.test.transaction;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.Version;
|
|
||||||
|
|
||||||
import org.hibernate.Session;
|
|
||||||
import org.hibernate.engine.transaction.spi.TransactionObserver;
|
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
|
||||||
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
|
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import static org.hamcrest.core.Is.is;
|
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Andrea Boriero
|
|
||||||
*/
|
|
||||||
public class TransactionRollbackTest extends BaseEntityManagerFunctionalTestCase {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class[] getAnnotatedClasses() {
|
|
||||||
return new Class[] {
|
|
||||||
Shipment.class
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@TestForIssue( jiraKey = "HHH-11407")
|
|
||||||
public void checkRollBackTransactionIsExecutedOnceWhenACommitFails() throws Exception {
|
|
||||||
EntityManager em = createEntityManager();
|
|
||||||
try {
|
|
||||||
final Session session = em.unwrap( Session.class );
|
|
||||||
final OperationCollectorObserver transactionObserver = new OperationCollectorObserver();
|
|
||||||
( (JdbcSessionOwner) session ).getTransactionCoordinator().addObserver( transactionObserver );
|
|
||||||
em.getTransaction().begin();
|
|
||||||
|
|
||||||
// given two inserted records
|
|
||||||
em.persist( new Shipment( "shipment-1", "INITIAL" ) );
|
|
||||||
em.persist( new Shipment( "shipment-2", "INITIAL" ) );
|
|
||||||
|
|
||||||
em.flush();
|
|
||||||
em.clear();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// when provoking a duplicate-key exception
|
|
||||||
em.persist( new Shipment( "shipment-1", "INITIAL" ) );
|
|
||||||
em.getTransaction().commit();
|
|
||||||
fail( "Expected exception was not raised" );
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
// Nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
assertThat( transactionObserver.getUnSuccessfulAfterCompletion(), is( 1 ) );
|
|
||||||
|
|
||||||
em.clear();
|
|
||||||
em.getTransaction().begin();
|
|
||||||
|
|
||||||
Shipment shipment = em.find( Shipment.class, "shipment-1" );
|
|
||||||
if ( shipment != null ) {
|
|
||||||
em.remove( shipment );
|
|
||||||
}
|
|
||||||
|
|
||||||
shipment = em.find( Shipment.class, "shipment-2" );
|
|
||||||
if ( shipment != null ) {
|
|
||||||
em.remove( shipment );
|
|
||||||
}
|
|
||||||
|
|
||||||
em.getTransaction().commit();
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
em.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Entity(name = "Shipment")
|
|
||||||
public class Shipment {
|
|
||||||
|
|
||||||
@Id
|
|
||||||
private String id;
|
|
||||||
|
|
||||||
@Version
|
|
||||||
private long version;
|
|
||||||
|
|
||||||
private String state;
|
|
||||||
|
|
||||||
Shipment() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Shipment(String id, String state) {
|
|
||||||
this.id = id;
|
|
||||||
this.state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getVersion() {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVersion(long version) {
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setState(String state) {
|
|
||||||
this.state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private class OperationCollectorObserver implements TransactionObserver {
|
|
||||||
int unSuccessfulAfterCompletion;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterBegin() {
|
|
||||||
// Nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void beforeCompletion() {
|
|
||||||
// Nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterCompletion(boolean successful, boolean delayed) {
|
|
||||||
if ( !successful ) {
|
|
||||||
unSuccessfulAfterCompletion++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getUnSuccessfulAfterCompletion() {
|
|
||||||
return unSuccessfulAfterCompletion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -4,11 +4,10 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.jpa.test.transaction;
|
package org.hibernate.orm.test.jpa.transaction;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
@ -26,44 +25,48 @@ import javax.transaction.Status;
|
||||||
import javax.transaction.TransactionManager;
|
import javax.transaction.TransactionManager;
|
||||||
|
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl;
|
import org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl;
|
||||||
import org.hibernate.internal.SessionImpl;
|
import org.hibernate.internal.SessionImpl;
|
||||||
import org.hibernate.jpa.AvailableSettings;
|
import org.hibernate.jpa.test.transaction.Book;
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.jta.TestingJtaBootstrap;
|
|
||||||
import org.hibernate.testing.jta.TestingJtaPlatformImpl;
|
import org.hibernate.testing.jta.TestingJtaPlatformImpl;
|
||||||
import org.junit.After;
|
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||||
import org.junit.Test;
|
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;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.core.Is.is;
|
import static org.hamcrest.core.Is.is;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrea Boriero
|
* @author Andrea Boriero
|
||||||
*/
|
*/
|
||||||
public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManagerFunctionalTestCase {
|
@Jpa(
|
||||||
@Override
|
annotatedClasses = {
|
||||||
protected void addConfigOptions(Map options) {
|
Book.class,
|
||||||
super.addConfigOptions( options );
|
CloseEntityManagerWithActiveTransactionTest.Container.class,
|
||||||
TestingJtaBootstrap.prepare( options );
|
CloseEntityManagerWithActiveTransactionTest.Box.class,
|
||||||
options.put( AvailableSettings.TRANSACTION_TYPE, "JTA" );
|
CloseEntityManagerWithActiveTransactionTest.Muffin.class,
|
||||||
options.put( org.hibernate.cfg.AvailableSettings.JPA_TRANSACTION_COMPLIANCE, "true" );
|
CloseEntityManagerWithActiveTransactionTest.SmallBox.class
|
||||||
}
|
},
|
||||||
|
integrationSettings = {
|
||||||
|
@Setting(name = AvailableSettings.CONNECTION_PROVIDER, value = "org.hibernate.testing.jta.JtaAwareConnectionProviderImpl"),
|
||||||
|
@Setting(name = AvailableSettings.JPA_TRANSACTION_TYPE, value = "JTA"),
|
||||||
|
@Setting(name = AvailableSettings.JPA_TRANSACTION_COMPLIANCE, value = "true")
|
||||||
|
},
|
||||||
|
nonStringValueSettingProviders = { JtaPlatformNonStringValueSettingProvider.class }
|
||||||
|
)
|
||||||
|
public class CloseEntityManagerWithActiveTransactionTest {
|
||||||
|
|
||||||
@Override
|
@AfterEach
|
||||||
public Class[] getAnnotatedClasses() {
|
public void tearDown(EntityManagerFactoryScope scope) throws Exception {
|
||||||
return new Class[] {
|
|
||||||
Book.class, Container.class, Box.class, Muffin.class, SmallBox.class
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
EntityManager em = getOrCreateEntityManager();
|
EntityManager em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
try {
|
try {
|
||||||
em.createQuery( "delete from Muffin" ).executeUpdate();
|
em.createQuery( "delete from Muffin" ).executeUpdate();
|
||||||
em.createQuery( "delete from Box" ).executeUpdate();
|
em.createQuery( "delete from Box" ).executeUpdate();
|
||||||
|
@ -71,8 +74,8 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
final TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
|
final TransactionManager transactionManager = TestingJtaPlatformImpl.INSTANCE.getTransactionManager();
|
||||||
if ( transactionManager.getTransaction() != null && transactionManager.getTransaction()
|
if ( transactionManager.getTransaction() != null &&
|
||||||
.getStatus() == Status.STATUS_ACTIVE ) {
|
transactionManager.getTransaction().getStatus() == Status.STATUS_ACTIVE ) {
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -86,9 +89,9 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestForIssue(jiraKey = "HHH-10942")
|
@TestForIssue(jiraKey = "HHH-10942")
|
||||||
public void testPersistThenCloseWithAnActiveTransaction() throws Exception {
|
public void testPersistThenCloseWithAnActiveTransaction(EntityManagerFactoryScope scope) throws Exception {
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
EntityManager em = getOrCreateEntityManager();
|
EntityManager em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
try {
|
try {
|
||||||
Box box = new Box();
|
Box box = new Box();
|
||||||
box.setColor( "red-and-white" );
|
box.setColor( "red-and-white" );
|
||||||
|
@ -109,7 +112,7 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
em = getOrCreateEntityManager();
|
em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
try {
|
try {
|
||||||
final List results = em.createQuery( "from Box" ).getResultList();
|
final List results = em.createQuery( "from Box" ).getResultList();
|
||||||
assertThat( results.size(), is( 1 ) );
|
assertThat( results.size(), is( 1 ) );
|
||||||
|
@ -120,10 +123,10 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestForIssue( jiraKey = "HHH-11166")
|
@TestForIssue(jiraKey = "HHH-11166")
|
||||||
public void testMergeThenCloseWithAnActiveTransaction() throws Exception {
|
public void testMergeThenCloseWithAnActiveTransaction(EntityManagerFactoryScope scope) throws Exception {
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
EntityManager em = getOrCreateEntityManager();
|
EntityManager em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
try {
|
try {
|
||||||
Box box = new Box();
|
Box box = new Box();
|
||||||
box.setColor( "red-and-white" );
|
box.setColor( "red-and-white" );
|
||||||
|
@ -132,7 +135,7 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
|
||||||
|
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
em = getOrCreateEntityManager();
|
em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
|
|
||||||
Muffin muffin = new Muffin();
|
Muffin muffin = new Muffin();
|
||||||
muffin.setKind( "blueberry" );
|
muffin.setKind( "blueberry" );
|
||||||
|
@ -157,7 +160,7 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
em = getOrCreateEntityManager();
|
em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
try {
|
try {
|
||||||
final List<Box> boxes = em.createQuery( "from Box" ).getResultList();
|
final List<Box> boxes = em.createQuery( "from Box" ).getResultList();
|
||||||
assertThat( boxes.size(), is( 1 ) );
|
assertThat( boxes.size(), is( 1 ) );
|
||||||
|
@ -169,21 +172,21 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestForIssue( jiraKey = "HHH-11269")
|
@TestForIssue(jiraKey = "HHH-11269")
|
||||||
public void testMergeWithDeletionOrphanRemovalThenCloseWithAnActiveTransaction() throws Exception {
|
public void testMergeWithDeletionOrphanRemovalThenCloseWithAnActiveTransaction(EntityManagerFactoryScope scope) throws Exception {
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
EntityManager em = getOrCreateEntityManager();
|
EntityManager em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
try {
|
try {
|
||||||
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 );
|
em.persist( box );
|
||||||
em.close();
|
em.close();
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
|
||||||
|
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
em = getOrCreateEntityManager();
|
em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
|
|
||||||
box.emptyBox();
|
box.emptyBox();
|
||||||
|
|
||||||
|
@ -206,11 +209,11 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
em = getOrCreateEntityManager();
|
em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
try {
|
try {
|
||||||
final List<SmallBox> boxes = em.createQuery( "from SmallBox" ).getResultList();
|
final List<SmallBox> boxes = em.createQuery( "from SmallBox" ).getResultList();
|
||||||
assertThat( boxes.size(), is( 1 ) );
|
assertThat( boxes.size(), is( 1 ) );
|
||||||
assertTrue( boxes.get( 0 ).isEmpty());
|
assertTrue( boxes.get( 0 ).isEmpty() );
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
em.close();
|
em.close();
|
||||||
|
@ -218,10 +221,10 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestForIssue( jiraKey = "HHH-11166")
|
@TestForIssue(jiraKey = "HHH-11166")
|
||||||
public void testUpdateThenCloseWithAnActiveTransaction() throws Exception {
|
public void testUpdateThenCloseWithAnActiveTransaction(EntityManagerFactoryScope scope) throws Exception {
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
EntityManager em = getOrCreateEntityManager();
|
EntityManager em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
try {
|
try {
|
||||||
Box box = new Box();
|
Box box = new Box();
|
||||||
box.setColor( "red-and-white" );
|
box.setColor( "red-and-white" );
|
||||||
|
@ -230,7 +233,7 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
|
||||||
|
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
em = getOrCreateEntityManager();
|
em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
box = em.find( Box.class, box.getId() );
|
box = em.find( Box.class, box.getId() );
|
||||||
Muffin muffin = new Muffin();
|
Muffin muffin = new Muffin();
|
||||||
muffin.setKind( "blueberry" );
|
muffin.setKind( "blueberry" );
|
||||||
|
@ -252,7 +255,7 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
em = getOrCreateEntityManager();
|
em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
try {
|
try {
|
||||||
final List<Box> boxes = em.createQuery( "from Box" ).getResultList();
|
final List<Box> boxes = em.createQuery( "from Box" ).getResultList();
|
||||||
assertThat( boxes.size(), is( 1 ) );
|
assertThat( boxes.size(), is( 1 ) );
|
||||||
|
@ -264,10 +267,10 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestForIssue( jiraKey = "HHH-11166")
|
@TestForIssue(jiraKey = "HHH-11166")
|
||||||
public void testRemoveThenCloseWithAnActiveTransaction() throws Exception {
|
public void testRemoveThenCloseWithAnActiveTransaction(EntityManagerFactoryScope scope) throws Exception {
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
EntityManager em = getOrCreateEntityManager();
|
EntityManager em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
try {
|
try {
|
||||||
Box box = new Box();
|
Box box = new Box();
|
||||||
box.setColor( "red-and-white" );
|
box.setColor( "red-and-white" );
|
||||||
|
@ -279,7 +282,7 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
|
||||||
|
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
em = getOrCreateEntityManager();
|
em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
box = em.find( Box.class, box.getId() );
|
box = em.find( Box.class, box.getId() );
|
||||||
em.remove( box );
|
em.remove( box );
|
||||||
|
|
||||||
|
@ -299,7 +302,7 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
em = getOrCreateEntityManager();
|
em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
try {
|
try {
|
||||||
final List<Box> boxes = em.createQuery( "from Box" ).getResultList();
|
final List<Box> boxes = em.createQuery( "from Box" ).getResultList();
|
||||||
assertThat( boxes.size(), is( 0 ) );
|
assertThat( boxes.size(), is( 0 ) );
|
||||||
|
@ -311,9 +314,9 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestForIssue(jiraKey = "HHH-11099")
|
@TestForIssue(jiraKey = "HHH-11099")
|
||||||
public void testCommitReleasesLogicalConnection() throws Exception {
|
public void testCommitReleasesLogicalConnection(EntityManagerFactoryScope scope) throws Exception {
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
EntityManager em = getOrCreateEntityManager();
|
EntityManager em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
try {
|
try {
|
||||||
Box box = new Box();
|
Box box = new Box();
|
||||||
box.setColor( "red-and-white" );
|
box.setColor( "red-and-white" );
|
||||||
|
@ -396,30 +399,30 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
@Entity(name = "SmallBox")
|
@Entity(name = "SmallBox")
|
||||||
public static class SmallBox extends Container {
|
public static class SmallBox extends Container {
|
||||||
|
|
||||||
@OneToOne(cascade = {CascadeType.MERGE,
|
@OneToOne(cascade = {
|
||||||
|
CascadeType.MERGE,
|
||||||
CascadeType.REMOVE,
|
CascadeType.REMOVE,
|
||||||
CascadeType.REFRESH,
|
CascadeType.REFRESH,
|
||||||
CascadeType.PERSIST
|
CascadeType.PERSIST
|
||||||
}, orphanRemoval = true)
|
}, orphanRemoval = true)
|
||||||
private Muffin muffin;
|
private Muffin muffin;
|
||||||
|
|
||||||
public SmallBox(){}
|
public SmallBox() {
|
||||||
|
}
|
||||||
|
|
||||||
public SmallBox(Muffin muffin) {
|
public SmallBox(Muffin muffin) {
|
||||||
this.muffin = muffin;
|
this.muffin = muffin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void emptyBox(){
|
public void emptyBox() {
|
||||||
muffin = null;
|
muffin = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty(){
|
public boolean isEmpty() {
|
||||||
return muffin == null;
|
return muffin == null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Entity(name = "Muffin")
|
@Entity(name = "Muffin")
|
||||||
public static class Muffin {
|
public static class Muffin {
|
||||||
|
|
||||||
|
@ -447,10 +450,4 @@ public class CloseEntityManagerWithActiveTransactionTest extends BaseEntityManag
|
||||||
this.kind = kind;
|
this.kind = kind;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface Action{
|
|
||||||
void execute();
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -6,7 +6,6 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.test.jpa.transaction;
|
package org.hibernate.orm.test.jpa.transaction;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.EntityTransaction;
|
import javax.persistence.EntityTransaction;
|
||||||
|
|
||||||
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||||
|
@ -14,9 +13,9 @@ import org.hibernate.testing.orm.junit.Jpa;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.junit.Assert.assertSame;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrea Boriero
|
* @author Andrea Boriero
|
||||||
|
|
|
@ -8,8 +8,7 @@ package org.hibernate.orm.test.jpa.transaction;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
|
||||||
import org.hibernate.jpa.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.jpa.test.transaction.Book;
|
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||||
|
@ -24,11 +23,11 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
*/
|
*/
|
||||||
@Jpa(
|
@Jpa(
|
||||||
integrationSettings = {
|
integrationSettings = {
|
||||||
@Setting(name = AvailableSettings.TRANSACTION_TYPE, value = "JTA"),
|
@Setting(name = AvailableSettings.JPA_TRANSACTION_TYPE, value = "JTA"),
|
||||||
@Setting(name = org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER, value = "org.hibernate.testing.jta.JtaAwareConnectionProviderImpl"),
|
@Setting(name = org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER, value = "org.hibernate.testing.jta.JtaAwareConnectionProviderImpl"),
|
||||||
@Setting( name = org.hibernate.cfg.AvailableSettings.JPA_TRANSACTION_COMPLIANCE, value = "true")
|
@Setting( name = org.hibernate.cfg.AvailableSettings.JPA_TRANSACTION_COMPLIANCE, value = "true")
|
||||||
},
|
},
|
||||||
nonStringValueSettingProviders = { SynchronizationTypeTest.JtaPlatformNonStringValueSettingProvider.class }
|
nonStringValueSettingProviders = { JtaPlatformNonStringValueSettingProvider.class }
|
||||||
)
|
)
|
||||||
public class JtaGetTransactionThrowsExceptionTest {
|
public class JtaGetTransactionThrowsExceptionTest {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.jpa.transaction;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
|
||||||
|
import org.hibernate.testing.jta.TestingJtaPlatformImpl;
|
||||||
|
import org.hibernate.testing.orm.jpa.NonStringValueSettingProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jan Schatteman
|
||||||
|
*/
|
||||||
|
public class JtaPlatformNonStringValueSettingProvider extends NonStringValueSettingProvider {
|
||||||
|
@Override
|
||||||
|
public String getKey() {
|
||||||
|
return AvailableSettings.JTA_PLATFORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValue() {
|
||||||
|
return TestingJtaPlatformImpl.INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.jpa.transaction;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EntityTransaction;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
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.hamcrest.core.Is.is;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrea Boriero
|
||||||
|
*/
|
||||||
|
@Jpa(
|
||||||
|
annotatedClasses = { JtaReusingEntityTransactionTest.TestEntity.class },
|
||||||
|
integrationSettings = {
|
||||||
|
@Setting(name = org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER, value = "org.hibernate.testing.jta.JtaAwareConnectionProviderImpl"),
|
||||||
|
@Setting(name = org.hibernate.cfg.AvailableSettings.JPA_TRANSACTION_TYPE, value = "JTA")
|
||||||
|
},
|
||||||
|
nonStringValueSettingProviders = { JtaPlatformNonStringValueSettingProvider.class }
|
||||||
|
)
|
||||||
|
public class JtaReusingEntityTransactionTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void entityTransactionShouldBeReusableTest(EntityManagerFactoryScope scope) {
|
||||||
|
scope.inEntityManager(
|
||||||
|
entityManager -> {
|
||||||
|
EntityTransaction transaction = null;
|
||||||
|
try {
|
||||||
|
transaction = entityManager.getTransaction();
|
||||||
|
entityManager.persist( new TestEntity() );
|
||||||
|
transaction.begin();
|
||||||
|
transaction.commit();
|
||||||
|
transaction.begin();
|
||||||
|
entityManager.persist( new TestEntity() );
|
||||||
|
transaction.commit();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if ( transaction != null && transaction.isActive() ) {
|
||||||
|
transaction.rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
entityManager -> {
|
||||||
|
List<TestEntity> results = entityManager.createQuery( "from TestEntity" ).getResultList();
|
||||||
|
assertThat( results.size(), is( 2 ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "TestEntity")
|
||||||
|
public static class TestEntity {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,15 +15,13 @@ import javax.persistence.criteria.CriteriaUpdate;
|
||||||
|
|
||||||
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.jpa.AvailableSettings;
|
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.jpa.test.transaction.TransactionJoiningTest;
|
|
||||||
import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl;
|
import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl;
|
||||||
|
|
||||||
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.jpa.NonStringValueSettingProvider;
|
|
||||||
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.ExtraAssertions;
|
||||||
import org.hibernate.testing.orm.junit.Jpa;
|
import org.hibernate.testing.orm.junit.Jpa;
|
||||||
|
@ -46,26 +44,14 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||||
@Jpa(
|
@Jpa(
|
||||||
annotatedClasses = { Book.class },
|
annotatedClasses = { Book.class },
|
||||||
integrationSettings = {
|
integrationSettings = {
|
||||||
@Setting(name = AvailableSettings.TRANSACTION_TYPE, value = "JTA"),
|
@Setting(name = AvailableSettings.JPA_TRANSACTION_TYPE, value = "JTA"),
|
||||||
@Setting(name = org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER, value = "org.hibernate.testing.jta.JtaAwareConnectionProviderImpl"),
|
@Setting(name = org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER, value = "org.hibernate.testing.jta.JtaAwareConnectionProviderImpl"),
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
nonStringValueSettingProviders = { SynchronizationTypeTest.JtaPlatformNonStringValueSettingProvider.class }
|
nonStringValueSettingProviders = { JtaPlatformNonStringValueSettingProvider.class }
|
||||||
)
|
)
|
||||||
public class SynchronizationTypeTest {
|
public class SynchronizationTypeTest {
|
||||||
public static class JtaPlatformNonStringValueSettingProvider extends NonStringValueSettingProvider {
|
|
||||||
@Override
|
|
||||||
public String getKey() {
|
|
||||||
return org.hibernate.cfg.AvailableSettings.JTA_PLATFORM;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getValue() {
|
|
||||||
return TestingJtaPlatformImpl.INSTANCE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnSynchronizedExplicitJoinHandling(EntityManagerFactoryScope scope) throws Exception {
|
public void testUnSynchronizedExplicitJoinHandling(EntityManagerFactoryScope scope) throws Exception {
|
||||||
|
|
|
@ -4,9 +4,8 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.jpa.test.transaction;
|
package org.hibernate.orm.test.jpa.transaction;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.PersistenceException;
|
import javax.persistence.PersistenceException;
|
||||||
|
@ -18,67 +17,81 @@ import org.hibernate.HibernateException;
|
||||||
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.internal.SessionImpl;
|
import org.hibernate.internal.SessionImpl;
|
||||||
import org.hibernate.jpa.AvailableSettings;
|
import org.hibernate.jpa.test.transaction.Book;
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
|
||||||
import org.hibernate.orm.test.jpa.transaction.TransactionJoinHandlingChecker;
|
|
||||||
import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl;
|
import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl;
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.jta.TestingJtaBootstrap;
|
|
||||||
import org.hibernate.testing.jta.TestingJtaPlatformImpl;
|
import org.hibernate.testing.jta.TestingJtaPlatformImpl;
|
||||||
import org.hibernate.testing.junit4.ExtraAssertions;
|
import org.hibernate.testing.orm.junit.ExtraAssertions;
|
||||||
import org.junit.Test;
|
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Jpa;
|
||||||
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.junit.Assert.assertTrue;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Largely a copy of {@link org.hibernate.test.jpa.txn.JtaTransactionJoiningTest}
|
* Largely a copy of {@link org.hibernate.test.jpa.txn.JtaTransactionJoiningTest}
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class TransactionJoiningTest extends BaseEntityManagerFunctionalTestCase {
|
@Jpa(
|
||||||
@Override
|
annotatedClasses = {
|
||||||
protected void addConfigOptions(Map options) {
|
Book.class
|
||||||
super.addConfigOptions( options );
|
},
|
||||||
TestingJtaBootstrap.prepare( options );
|
integrationSettings = {
|
||||||
options.put( AvailableSettings.TRANSACTION_TYPE, "JTA" );
|
@Setting(name = org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER, value = "org.hibernate.testing.jta.JtaAwareConnectionProviderImpl"),
|
||||||
}
|
@Setting(name = org.hibernate.cfg.AvailableSettings.JPA_TRANSACTION_TYPE, value = "JTA")
|
||||||
|
},
|
||||||
|
nonStringValueSettingProviders = { JtaPlatformNonStringValueSettingProvider.class }
|
||||||
|
)
|
||||||
|
public class TransactionJoiningTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExplicitJoining() throws Exception {
|
public void testExplicitJoining(EntityManagerFactoryScope scope) throws Exception {
|
||||||
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
|
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
|
||||||
|
|
||||||
EntityManager entityManager = entityManagerFactory().createEntityManager( SynchronizationType.UNSYNCHRONIZED );
|
EntityManager entityManager = scope.getEntityManagerFactory()
|
||||||
TransactionJoinHandlingChecker.validateExplicitJoiningHandling( entityManager );
|
.createEntityManager( SynchronizationType.UNSYNCHRONIZED );
|
||||||
|
try {
|
||||||
|
TransactionJoinHandlingChecker.validateExplicitJoiningHandling( entityManager );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
entityManager.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("EmptyCatchBlock")
|
public void testExplicitJoiningTransactionRequiredException(EntityManagerFactoryScope scope) {
|
||||||
public void testExplicitJoiningTransactionRequiredException() throws Exception {
|
|
||||||
// explicitly calling EntityManager#joinTransaction outside of an active transaction should cause
|
// explicitly calling EntityManager#joinTransaction outside of an active transaction should cause
|
||||||
// a TransactionRequiredException to be thrown
|
// a TransactionRequiredException to be thrown
|
||||||
|
|
||||||
EntityManager entityManager = entityManagerFactory().createEntityManager();
|
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager();
|
||||||
assertFalse("setup problem", JtaStatusHelper.isActive(TestingJtaPlatformImpl.INSTANCE.getTransactionManager()));
|
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ), "setup problem" );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
entityManager.joinTransaction();
|
Assertions.assertThrows(
|
||||||
fail( "Expected joinTransaction() to fail since there is no active JTA transaction" );
|
TransactionRequiredException.class,
|
||||||
|
entityManager::joinTransaction,
|
||||||
|
"Expected joinTransaction() to fail since there is no active JTA transaction"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
catch (TransactionRequiredException expected) {
|
finally {
|
||||||
|
entityManager.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testImplicitJoining() 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() ) );
|
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
|
||||||
|
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
EntityManager entityManager = entityManagerFactory().createEntityManager();
|
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager();
|
||||||
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
|
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
|
||||||
|
|
||||||
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
|
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
|
||||||
|
@ -101,11 +114,11 @@ public class TransactionJoiningTest extends BaseEntityManagerFunctionalTestCase
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestForIssue(jiraKey = "HHH-10807")
|
@TestForIssue(jiraKey = "HHH-10807")
|
||||||
public void testIsJoinedAfterMarkedForRollbackImplict() throws Exception {
|
public void testIsJoinedAfterMarkedForRollbackImplicit(EntityManagerFactoryScope scope) throws Exception {
|
||||||
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
|
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
|
||||||
|
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
EntityManager entityManager = entityManagerFactory().createEntityManager();
|
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager();
|
||||||
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
|
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
|
||||||
|
|
||||||
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
|
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
|
||||||
|
@ -123,20 +136,25 @@ public class TransactionJoiningTest extends BaseEntityManagerFunctionalTestCase
|
||||||
assertTrue( transactionCoordinator.isJoined() );
|
assertTrue( transactionCoordinator.isJoined() );
|
||||||
assertTrue( entityManager.isJoinedToTransaction() );
|
assertTrue( entityManager.isJoinedToTransaction() );
|
||||||
|
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
|
try {
|
||||||
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
|
||||||
entityManager.close();
|
entityManager.close();
|
||||||
assertFalse( entityManager.isOpen() );
|
assertFalse( entityManager.isOpen() );
|
||||||
assertFalse( session.isOpen() );
|
assertFalse( session.isOpen() );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
// ensure the entityManager is closed in case the rollback call fails
|
||||||
|
entityManager.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestForIssue(jiraKey = "HHH-10807")
|
@TestForIssue(jiraKey = "HHH-10807")
|
||||||
public void testIsJoinedAfterMarkedForRollbackExplicit() throws Exception {
|
public void testIsJoinedAfterMarkedForRollbackExplicit(EntityManagerFactoryScope scope) throws Exception {
|
||||||
|
|
||||||
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
|
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
|
||||||
|
|
||||||
EntityManager entityManager = entityManagerFactory().createEntityManager( SynchronizationType.UNSYNCHRONIZED );
|
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager( SynchronizationType.UNSYNCHRONIZED );
|
||||||
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
|
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
|
||||||
assertTrue( entityManager.isOpen() );
|
assertTrue( entityManager.isOpen() );
|
||||||
assertTrue( session.isOpen() );
|
assertTrue( session.isOpen() );
|
||||||
|
@ -157,19 +175,25 @@ public class TransactionJoiningTest extends BaseEntityManagerFunctionalTestCase
|
||||||
assertTrue( transactionCoordinator.isJoined() );
|
assertTrue( transactionCoordinator.isJoined() );
|
||||||
assertTrue( entityManager.isJoinedToTransaction() );
|
assertTrue( entityManager.isJoinedToTransaction() );
|
||||||
|
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
|
try {
|
||||||
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
|
||||||
|
|
||||||
entityManager.close();
|
entityManager.close();
|
||||||
assertFalse( entityManager.isOpen() );
|
assertFalse( entityManager.isOpen() );
|
||||||
assertFalse( session.isOpen() );
|
assertFalse( session.isOpen() );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
// ensure the entityManager is closed in case the rollback call fails
|
||||||
|
entityManager.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCloseAfterCommit() throws Exception {
|
public void testCloseAfterCommit(EntityManagerFactoryScope scope) throws Exception {
|
||||||
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
|
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
|
||||||
|
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
EntityManager entityManager = entityManagerFactory().createEntityManager();
|
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager();
|
||||||
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
|
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
|
||||||
|
|
||||||
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
|
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
|
||||||
|
@ -181,21 +205,27 @@ public class TransactionJoiningTest extends BaseEntityManagerFunctionalTestCase
|
||||||
|
|
||||||
assertTrue( entityManager.isOpen() );
|
assertTrue( entityManager.isOpen() );
|
||||||
assertTrue( session.isOpen() );
|
assertTrue( session.isOpen() );
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
|
try {
|
||||||
assertTrue( entityManager.isOpen() );
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
|
||||||
assertTrue( session.isOpen() );
|
assertTrue( entityManager.isOpen() );
|
||||||
|
assertTrue( session.isOpen() );
|
||||||
|
|
||||||
entityManager.close();
|
entityManager.close();
|
||||||
assertFalse( entityManager.isOpen() );
|
assertFalse( entityManager.isOpen() );
|
||||||
assertFalse( session.isOpen() );
|
assertFalse( session.isOpen() );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
// ensure the entityManager is closed in case the commit call fails
|
||||||
|
entityManager.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testImplicitJoiningWithExtraSynchronization() throws Exception {
|
public void testImplicitJoiningWithExtraSynchronization(EntityManagerFactoryScope scope) throws Exception {
|
||||||
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
|
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
|
||||||
|
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
EntityManager entityManager = entityManagerFactory().createEntityManager();
|
EntityManager entityManager = scope.getEntityManagerFactory().createEntityManager();
|
||||||
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
|
SharedSessionContractImplementor session = entityManager.unwrap( SharedSessionContractImplementor.class );
|
||||||
|
|
||||||
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
|
ExtraAssertions.assertTyping( JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator() );
|
||||||
|
@ -209,7 +239,7 @@ public class TransactionJoiningTest extends BaseEntityManagerFunctionalTestCase
|
||||||
|
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In certain JTA environments (JBossTM, etc.), a background thread (reaper)
|
* In certain JTA environments (JBossTM, etc.), a background thread (reaper)
|
||||||
* can rollback a transaction if it times out. These timeouts are rare and
|
* can rollback a transaction if it times out. These timeouts are rare and
|
||||||
|
@ -220,55 +250,51 @@ public class TransactionJoiningTest extends BaseEntityManagerFunctionalTestCase
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@TestForIssue(jiraKey = "HHH-7910")
|
@TestForIssue(jiraKey = "HHH-7910")
|
||||||
public void testMultiThreadTransactionTimeout() throws Exception {
|
public void testMultiThreadTransactionTimeout(EntityManagerFactoryScope scope) throws Exception {
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
|
|
||||||
EntityManager em = entityManagerFactory().createEntityManager();
|
EntityManager em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
final SessionImpl sImpl = em.unwrap( SessionImpl.class );
|
try {
|
||||||
|
final SessionImpl sImpl = em.unwrap( SessionImpl.class );
|
||||||
|
|
||||||
final CountDownLatch latch = new CountDownLatch( 1 );
|
final CountDownLatch latch = new CountDownLatch( 1 );
|
||||||
|
|
||||||
Thread thread = new Thread() {
|
Thread thread = new Thread( () -> {
|
||||||
public void run() {
|
( (JtaTransactionCoordinatorImpl) sImpl.getTransactionCoordinator() ).getSynchronizationCallbackCoordinator()
|
||||||
((JtaTransactionCoordinatorImpl)sImpl.getTransactionCoordinator()).getSynchronizationCallbackCoordinator()
|
|
||||||
.afterCompletion( Status.STATUS_ROLLEDBACK );
|
.afterCompletion( Status.STATUS_ROLLEDBACK );
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
|
} );
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
latch.await();
|
||||||
|
|
||||||
|
boolean caught = false;
|
||||||
|
try {
|
||||||
|
em.persist( new Book( "The Book of Foo", 1 ) );
|
||||||
}
|
}
|
||||||
};
|
catch (PersistenceException e) {
|
||||||
thread.start();
|
caught = e.getCause().getClass().equals( HibernateException.class );
|
||||||
|
}
|
||||||
|
assertTrue( caught );
|
||||||
|
|
||||||
latch.await();
|
// Ensure that the connection was closed by the background thread.
|
||||||
|
caught = false;
|
||||||
|
try {
|
||||||
|
em.createQuery( "from Book" ).getResultList();
|
||||||
|
}
|
||||||
|
catch (PersistenceException e) {
|
||||||
|
// HHH-9312
|
||||||
|
caught = true;
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
caught = true;
|
||||||
|
}
|
||||||
|
assertTrue( caught );
|
||||||
|
|
||||||
boolean caught = false;
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
|
||||||
try {
|
|
||||||
em.persist( new Book( "The Book of Foo", 1 ) );
|
|
||||||
}
|
}
|
||||||
catch ( PersistenceException e ) {
|
finally {
|
||||||
caught = e.getCause().getClass().equals( HibernateException.class );
|
em.close();
|
||||||
}
|
}
|
||||||
assertTrue( caught );
|
|
||||||
|
|
||||||
// Ensure that the connection was closed by the background thread.
|
|
||||||
caught = false;
|
|
||||||
try {
|
|
||||||
em.createQuery( "from Book" ).getResultList();
|
|
||||||
}
|
|
||||||
catch ( PersistenceException e ) {
|
|
||||||
// HHH-9312
|
|
||||||
caught = true;
|
|
||||||
}catch (Exception e){
|
|
||||||
caught = true;
|
|
||||||
}
|
|
||||||
assertTrue( caught );
|
|
||||||
|
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
|
|
||||||
em.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class[] getAnnotatedClasses() {
|
|
||||||
return new Class[] {
|
|
||||||
Book.class
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.jpa.transaction;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Version;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.engine.transaction.spi.TransactionObserver;
|
||||||
|
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Jpa;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.core.Is.is;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrea Boriero
|
||||||
|
*/
|
||||||
|
@Jpa(annotatedClasses = {
|
||||||
|
TransactionRollbackTest.Shipment.class
|
||||||
|
})
|
||||||
|
public class TransactionRollbackTest {
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void tearDown(EntityManagerFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
entityManager -> {
|
||||||
|
entityManager.createQuery( "delete from Shipment" ).executeUpdate();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue( jiraKey = "HHH-11407")
|
||||||
|
public void checkRollBackTransactionIsExecutedOnceWhenACommitFails(EntityManagerFactoryScope scope) {
|
||||||
|
scope.inEntityManager(
|
||||||
|
entityManager -> {
|
||||||
|
final Session session = entityManager.unwrap( Session.class );
|
||||||
|
final OperationCollectorObserver transactionObserver = new OperationCollectorObserver();
|
||||||
|
( (JdbcSessionOwner) session ).getTransactionCoordinator().addObserver( transactionObserver );
|
||||||
|
entityManager.getTransaction().begin();
|
||||||
|
|
||||||
|
// given two inserted records
|
||||||
|
entityManager.persist( new Shipment( "shipment-1", "INITIAL" ) );
|
||||||
|
entityManager.persist( new Shipment( "shipment-2", "INITIAL" ) );
|
||||||
|
|
||||||
|
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"
|
||||||
|
);
|
||||||
|
|
||||||
|
assertThat( transactionObserver.getUnSuccessfulAfterCompletion(), is( 1 ) );
|
||||||
|
|
||||||
|
entityManager.clear();
|
||||||
|
entityManager.getTransaction().begin();
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "Shipment")
|
||||||
|
public class Shipment {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Version
|
||||||
|
private long version;
|
||||||
|
|
||||||
|
private String state;
|
||||||
|
|
||||||
|
Shipment() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Shipment(String id, String state) {
|
||||||
|
this.id = id;
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(long version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState(String state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class OperationCollectorObserver implements TransactionObserver {
|
||||||
|
int unSuccessfulAfterCompletion;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterBegin() {
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeCompletion() {
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterCompletion(boolean successful, boolean delayed) {
|
||||||
|
if ( !successful ) {
|
||||||
|
unSuccessfulAfterCompletion++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUnSuccessfulAfterCompletion() {
|
||||||
|
return unSuccessfulAfterCompletion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,25 +4,23 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.jpa.test.transaction;
|
package org.hibernate.orm.test.jpa.transaction;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
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 java.util.Map;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.jpa.AvailableSettings;
|
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
|
||||||
|
|
||||||
import org.junit.Ignore;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import org.hibernate.testing.jta.TestingJtaBootstrap;
|
|
||||||
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.Jpa;
|
||||||
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
|
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recreate test failure that occurs when three threads share the same entity manager and
|
* Recreate test failure that occurs when three threads share the same entity manager and
|
||||||
|
@ -30,18 +28,19 @@ import static org.junit.Assert.fail;
|
||||||
*
|
*
|
||||||
* @author Scott Marlow
|
* @author Scott Marlow
|
||||||
*/
|
*/
|
||||||
public class TransactionRolledBackInDifferentThreadTest extends BaseEntityManagerFunctionalTestCase {
|
@Jpa(
|
||||||
@Override
|
integrationSettings = {
|
||||||
protected void addConfigOptions(Map options) {
|
@Setting(name = org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER, value = "org.hibernate.testing.jta.JtaAwareConnectionProviderImpl"),
|
||||||
super.addConfigOptions( options );
|
@Setting(name = org.hibernate.cfg.AvailableSettings.JPA_TRANSACTION_TYPE, value = "JTA")
|
||||||
TestingJtaBootstrap.prepare( options );
|
},
|
||||||
options.put( AvailableSettings.TRANSACTION_TYPE, "JTA" );
|
nonStringValueSettingProviders = { JtaPlatformNonStringValueSettingProvider.class }
|
||||||
}
|
)
|
||||||
|
public class TransactionRolledBackInDifferentThreadTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionRolledBackInDifferentThreadFailure() throws Exception {
|
public void testTransactionRolledBackInDifferentThreadFailure(EntityManagerFactoryScope scope) throws Exception {
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* The three test threads share the same entity manager.
|
* The three test threads share the same entity manager.
|
||||||
* The main test thread creates an EntityManager, joins it to the transaction and ends the transaction.
|
* The main test thread creates an EntityManager, joins it to the transaction and ends the transaction.
|
||||||
* Test thread 1 joins the EntityManager to its transaction, sets rollbackonly and ends the transaction.
|
* Test thread 1 joins the EntityManager to its transaction, sets rollbackonly and ends the transaction.
|
||||||
|
@ -51,18 +50,18 @@ public class TransactionRolledBackInDifferentThreadTest extends BaseEntityManage
|
||||||
|
|
||||||
// main test thread
|
// main test thread
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
final EntityManager em = entityManagerFactory().createEntityManager();
|
final EntityManager em = scope.getEntityManagerFactory().createEntityManager();
|
||||||
em.joinTransaction();
|
em.joinTransaction();
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
|
|
||||||
|
|
||||||
// will be set to the failing exception
|
try {
|
||||||
final HibernateException[] transactionRolledBackInDifferentThreadException = new HibernateException[2];
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
|
||||||
transactionRolledBackInDifferentThreadException[0] = transactionRolledBackInDifferentThreadException[1] = null;
|
|
||||||
|
|
||||||
// background test thread 1
|
// will be set to the failing exception
|
||||||
final Runnable run1 = new Runnable() {
|
final HibernateException[] transactionRolledBackInDifferentThreadException = new HibernateException[2];
|
||||||
@Override
|
transactionRolledBackInDifferentThreadException[0] = transactionRolledBackInDifferentThreadException[1] = null;
|
||||||
public void run() {
|
|
||||||
|
// background test thread 1
|
||||||
|
final Runnable run1 = () -> {
|
||||||
try {
|
try {
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
||||||
em.joinTransaction();
|
em.joinTransaction();
|
||||||
|
@ -72,7 +71,7 @@ public class TransactionRolledBackInDifferentThreadTest extends BaseEntityManage
|
||||||
catch (javax.persistence.PersistenceException e) {
|
catch (javax.persistence.PersistenceException e) {
|
||||||
if ( e.getCause() instanceof HibernateException &&
|
if ( e.getCause() instanceof HibernateException &&
|
||||||
e.getCause().getMessage().equals( "Transaction was rolled back in a different thread!" ) ) {
|
e.getCause().getMessage().equals( "Transaction was rolled back in a different thread!" ) ) {
|
||||||
/**
|
/*
|
||||||
* Save the exception for the main test thread to fail
|
* Save the exception for the main test thread to fail
|
||||||
*/
|
*/
|
||||||
e.printStackTrace(); // show the error first
|
e.printStackTrace(); // show the error first
|
||||||
|
@ -81,7 +80,6 @@ public class TransactionRolledBackInDifferentThreadTest extends BaseEntityManage
|
||||||
}
|
}
|
||||||
catch (RollbackException ignored) {
|
catch (RollbackException ignored) {
|
||||||
// expected to see RollbackException: ARJUNA016053: Could not commit transaction.
|
// expected to see RollbackException: ARJUNA016053: Could not commit transaction.
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Throwable throwable) {
|
catch (Throwable throwable) {
|
||||||
throwable.printStackTrace();
|
throwable.printStackTrace();
|
||||||
|
@ -94,20 +92,15 @@ public class TransactionRolledBackInDifferentThreadTest extends BaseEntityManage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SystemException ignore) {
|
catch (SystemException ignore) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
// test thread 2
|
||||||
};
|
final Runnable run2 = () -> {
|
||||||
|
|
||||||
// test thread 2
|
|
||||||
final Runnable run2 = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
try {
|
||||||
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
|
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().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!
|
||||||
*/
|
*/
|
||||||
|
@ -117,7 +110,7 @@ public class TransactionRolledBackInDifferentThreadTest extends BaseEntityManage
|
||||||
catch (javax.persistence.PersistenceException e) {
|
catch (javax.persistence.PersistenceException e) {
|
||||||
if ( e.getCause() instanceof HibernateException &&
|
if ( e.getCause() instanceof HibernateException &&
|
||||||
e.getCause().getMessage().equals( "Transaction was rolled back in a different thread!" ) ) {
|
e.getCause().getMessage().equals( "Transaction was rolled back in a different thread!" ) ) {
|
||||||
/**
|
/*
|
||||||
* Save the exception for the main test thread to fail
|
* Save the exception for the main test thread to fail
|
||||||
*/
|
*/
|
||||||
e.printStackTrace(); // show the error first
|
e.printStackTrace(); // show the error first
|
||||||
|
@ -135,45 +128,36 @@ public class TransactionRolledBackInDifferentThreadTest extends BaseEntityManage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SystemException ignore) {
|
catch (SystemException ignore) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Thread thread = new Thread( run1, "test thread1" );
|
||||||
|
thread.start();
|
||||||
|
thread.join();
|
||||||
|
|
||||||
|
Thread thread2 = new Thread( run2, "test thread2" );
|
||||||
|
thread2.start();
|
||||||
|
thread2.join();
|
||||||
|
|
||||||
|
// show failure for exception caught in run2.run()
|
||||||
|
if ( transactionRolledBackInDifferentThreadException[0] != null
|
||||||
|
|| transactionRolledBackInDifferentThreadException[1] != null )
|
||||||
|
{
|
||||||
|
fail(
|
||||||
|
"failure in test thread 1 = " +
|
||||||
|
( transactionRolledBackInDifferentThreadException[0] != null ?
|
||||||
|
transactionRolledBackInDifferentThreadException[0].getMessage() :
|
||||||
|
"(none)" )
|
||||||
|
+ ", failure in test thread 2 = " +
|
||||||
|
( transactionRolledBackInDifferentThreadException[1] != null ?
|
||||||
|
transactionRolledBackInDifferentThreadException[1].getMessage() :
|
||||||
|
"(none)" )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
Thread thread = new Thread( run1, "test thread1" );
|
|
||||||
thread.start();
|
|
||||||
thread.join();
|
|
||||||
|
|
||||||
Thread thread2 = new Thread( run2, "test thread2" );
|
|
||||||
thread2.start();
|
|
||||||
thread2.join();
|
|
||||||
|
|
||||||
// show failure for exception caught in run2.run()
|
|
||||||
if ( transactionRolledBackInDifferentThreadException[0] != null
|
|
||||||
|| transactionRolledBackInDifferentThreadException[1] != null )
|
|
||||||
|
|
||||||
{
|
|
||||||
fail(
|
|
||||||
"failure in test thread 1 = " +
|
|
||||||
( transactionRolledBackInDifferentThreadException[0] != null ?
|
|
||||||
transactionRolledBackInDifferentThreadException[0].getMessage() :
|
|
||||||
"(none)" )
|
|
||||||
+ ", failure in test thread 2 = " +
|
|
||||||
( transactionRolledBackInDifferentThreadException[1] != null ?
|
|
||||||
transactionRolledBackInDifferentThreadException[1].getMessage() :
|
|
||||||
"(none)" )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class[] getAnnotatedClasses() {
|
|
||||||
return new Class[] {
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -63,18 +63,6 @@ public abstract class AbstractJtaBatchTest {
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class JtaPlatformNonStringValueSettingProvider extends NonStringValueSettingProvider {
|
|
||||||
@Override
|
|
||||||
public String getKey() {
|
|
||||||
return AvailableSettings.JTA_PLATFORM;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getValue() {
|
|
||||||
return TestingJtaPlatformImpl.INSTANCE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ConnectionNonStringValueSettingProvider extends NonStringValueSettingProvider {
|
public static class ConnectionNonStringValueSettingProvider extends NonStringValueSettingProvider {
|
||||||
@Override
|
@Override
|
||||||
public String getKey() {
|
public String getKey() {
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.hibernate.engine.jdbc.batch.internal.BatchingBatch;
|
||||||
import org.hibernate.engine.jdbc.batch.spi.Batch;
|
import org.hibernate.engine.jdbc.batch.spi.Batch;
|
||||||
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
||||||
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
||||||
|
import org.hibernate.orm.test.jpa.transaction.JtaPlatformNonStringValueSettingProvider;
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.jta.TestingJtaPlatformImpl;
|
import org.hibernate.testing.jta.TestingJtaPlatformImpl;
|
||||||
|
@ -55,7 +56,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
@Setting(name = AvailableSettings.STATEMENT_BATCH_SIZE, value = "50")
|
@Setting(name = AvailableSettings.STATEMENT_BATCH_SIZE, value = "50")
|
||||||
},
|
},
|
||||||
nonStringValueSettingProviders = {
|
nonStringValueSettingProviders = {
|
||||||
AbstractJtaBatchTest.JtaPlatformNonStringValueSettingProvider.class,
|
JtaPlatformNonStringValueSettingProvider.class,
|
||||||
AbstractJtaBatchTest.ConnectionNonStringValueSettingProvider.class,
|
AbstractJtaBatchTest.ConnectionNonStringValueSettingProvider.class,
|
||||||
JtaWithFailingBatchTest.BatchBuilderNonStringValueSettingProvider.class
|
JtaWithFailingBatchTest.BatchBuilderNonStringValueSettingProvider.class
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,7 @@ import java.sql.PreparedStatement;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.persistence.FlushModeType;
|
import javax.persistence.FlushModeType;
|
||||||
import javax.transaction.NotSupportedException;
|
|
||||||
import javax.transaction.Status;
|
import javax.transaction.Status;
|
||||||
import javax.transaction.SystemException;
|
|
||||||
import javax.transaction.TransactionManager;
|
import javax.transaction.TransactionManager;
|
||||||
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
@ -22,6 +20,7 @@ import org.hibernate.engine.jdbc.batch.internal.BatchingBatch;
|
||||||
import org.hibernate.engine.jdbc.batch.spi.Batch;
|
import org.hibernate.engine.jdbc.batch.spi.Batch;
|
||||||
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
import org.hibernate.engine.jdbc.batch.spi.BatchKey;
|
||||||
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
||||||
|
import org.hibernate.orm.test.jpa.transaction.JtaPlatformNonStringValueSettingProvider;
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.jta.TestingJtaPlatformImpl;
|
import org.hibernate.testing.jta.TestingJtaPlatformImpl;
|
||||||
|
@ -55,7 +54,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
@Setting(name = AvailableSettings.STATEMENT_BATCH_SIZE, value = "50")
|
@Setting(name = AvailableSettings.STATEMENT_BATCH_SIZE, value = "50")
|
||||||
},
|
},
|
||||||
nonStringValueSettingProviders = {
|
nonStringValueSettingProviders = {
|
||||||
AbstractJtaBatchTest.JtaPlatformNonStringValueSettingProvider.class,
|
JtaPlatformNonStringValueSettingProvider.class,
|
||||||
AbstractJtaBatchTest.ConnectionNonStringValueSettingProvider.class,
|
AbstractJtaBatchTest.ConnectionNonStringValueSettingProvider.class,
|
||||||
JtaWithStatementsBatchTest.BatchBuilderNonStringValueSettingProvider.class
|
JtaWithStatementsBatchTest.BatchBuilderNonStringValueSettingProvider.class
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue