HHH-7451 - Integrate Draft 7 of the JPA 2.1 spec : SynchronizationType

This commit is contained in:
Steve Ebersole 2012-07-17 17:44:12 -05:00
parent f8d06216e5
commit 6a65c3e7e6
9 changed files with 356 additions and 68 deletions

View File

@ -218,12 +218,17 @@ public class TransactionCoordinatorImpl implements TransactionCoordinator {
return;
}
if ( currentHibernateTransaction.getJoinStatus() != JoinStatus.JOINED ) {
// the transaction is not (yet) joined, see if we should join...
if ( ! transactionContext.shouldAutoJoinTransaction() ) {
// we are supposed to not auto join transactions; if the transaction is not marked for join
// we cannot go any further in attempting to join (register sync).
if ( currentHibernateTransaction.getJoinStatus() != JoinStatus.MARKED_FOR_JOINED ) {
LOG.debug( "Skipping JTA sync registration due to auto join checking" );
return;
}
}
}
// IMPL NOTE : At this point the local callback is the "maybe" one. The only time that needs to change is if
// we are able to successfully register the transaction synchronization in which case the local callback would become

View File

@ -24,6 +24,7 @@
package org.hibernate.ejb;
import javax.persistence.PersistenceContextType;
import javax.persistence.SynchronizationType;
import javax.persistence.spi.PersistenceUnitTransactionType;
import java.io.Serializable;
import java.util.Map;
@ -41,8 +42,9 @@ public abstract class AbstractEntityManagerImpl
protected AbstractEntityManagerImpl(
EntityManagerFactoryImpl entityManagerFactory,
PersistenceContextType type,
SynchronizationType synchronizationType,
PersistenceUnitTransactionType transactionType,
Map properties) {
super( entityManagerFactory, type, transactionType, properties );
super( entityManagerFactory, type, synchronizationType, transactionType, properties );
}
}

View File

@ -47,8 +47,13 @@ public class CriteriaUpdateImpl<T> extends AbstractManipulationCriteriaQuery<T>
}
@Override
@SuppressWarnings("unchecked")
public <Y, X extends Y> CriteriaUpdate<T> set(SingularAttribute<? super T, Y> singularAttribute, X value) {
addAssignment( getRoot().get( singularAttribute ), criteriaBuilder().literal( value ) );
final Path<Y> attributePath = getRoot().get( singularAttribute );
final Expression valueExpression = value == null
? criteriaBuilder().nullLiteral( attributePath.getJavaType() )
: criteriaBuilder().literal( value );
addAssignment( attributePath, valueExpression );
return this;
}
@ -61,8 +66,12 @@ public class CriteriaUpdateImpl<T> extends AbstractManipulationCriteriaQuery<T>
}
@Override
@SuppressWarnings("unchecked")
public <Y, X extends Y> CriteriaUpdate<T> set(Path<Y> attributePath, X value) {
addAssignment( attributePath, criteriaBuilder().literal( value ) );
final Expression valueExpression = value == null
? criteriaBuilder().nullLiteral( attributePath.getJavaType() )
: criteriaBuilder().literal( value );
addAssignment( attributePath, valueExpression );
return this;
}
@ -73,8 +82,13 @@ public class CriteriaUpdateImpl<T> extends AbstractManipulationCriteriaQuery<T>
}
@Override
@SuppressWarnings("unchecked")
public CriteriaUpdate<T> set(String attributeName, Object value) {
addAssignment( getRoot().get( attributeName ), criteriaBuilder().literal( value ) );
final Path attributePath = getRoot().get( attributeName );
final Expression valueExpression = value == null
? criteriaBuilder().nullLiteral( attributePath.getJavaType() )
: criteriaBuilder().literal( value );
addAssignment( attributePath, valueExpression );
return this;
}
@ -88,6 +102,9 @@ public class CriteriaUpdateImpl<T> extends AbstractManipulationCriteriaQuery<T>
+ ( (PathImplementor) attributePath ).getPathIdentifier() + "]"
);
}
if ( value == null ) {
throw new IllegalArgumentException( "Assignment value expression cannot be null. Did you mean to pass null as a literal?" );
}
assignments.add( new Assignment<Y>( (SingularAttributePath<Y>) attributePath, value ) );
}

View File

@ -50,14 +50,7 @@ import org.hibernate.Hibernate;
import org.hibernate.SessionFactory;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.ejb.AvailableSettings;
import org.hibernate.ejb.HibernateEntityManagerFactory;
import org.hibernate.ejb.HibernateQuery;
import org.hibernate.jpa.boot.internal.SettingsImpl;
import org.hibernate.jpa.criteria.CriteriaBuilderImpl;
import org.hibernate.jpa.internal.metamodel.MetamodelImpl;
import org.hibernate.jpa.internal.util.PersistenceUtilHelper;
import org.hibernate.engine.spi.NamedQueryDefinition;
import org.hibernate.engine.spi.NamedQueryDefinitionBuilder;
import org.hibernate.engine.spi.NamedSQLQueryDefinition;
@ -67,6 +60,12 @@ import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.UUIDGenerator;
import org.hibernate.internal.SessionFactoryImpl;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.jpa.AvailableSettings;
import org.hibernate.jpa.HibernateQuery;
import org.hibernate.jpa.boot.internal.SettingsImpl;
import org.hibernate.jpa.criteria.CriteriaBuilderImpl;
import org.hibernate.jpa.internal.metamodel.MetamodelImpl;
import org.hibernate.jpa.internal.util.PersistenceUtilHelper;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.service.ServiceRegistry;
@ -205,10 +204,16 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
}
public EntityManager createEntityManager(Map map) {
return createEntityManager( SynchronizationType.SYNCHRONIZED, map );
}
@Override
public EntityManager createEntityManager(SynchronizationType synchronizationType, Map map) {
//TODO support discardOnClose, persistencecontexttype?, interceptor,
return new EntityManagerImpl(
this,
PersistenceContextType.EXTENDED,
synchronizationType,
transactionType,
discardOnClose,
sessionInterceptorClass,
@ -216,12 +221,6 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
);
}
@Override
public EntityManager createEntityManager(SynchronizationType synchronizationType, Map map) {
// todo : implement it
throw new NotYetImplementedException( "Not yet implemented" );
}
public CriteriaBuilder getCriteriaBuilder() {
return criteriaBuilder;
}

View File

@ -25,6 +25,7 @@ package org.hibernate.jpa.internal;
import javax.persistence.PersistenceContextType;
import javax.persistence.PersistenceException;
import javax.persistence.SynchronizationType;
import javax.persistence.spi.PersistenceUnitTransactionType;
import java.util.Map;
@ -35,10 +36,10 @@ import org.hibernate.Interceptor;
import org.hibernate.Session;
import org.hibernate.annotations.common.util.ReflectHelper;
import org.hibernate.ejb.AbstractEntityManagerImpl;
import org.hibernate.ejb.AvailableSettings;
import org.hibernate.engine.spi.SessionBuilderImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SessionOwner;
import org.hibernate.jpa.AvailableSettings;
/**
* Hibernate implementation of {@link javax.persistence.EntityManager}.
@ -58,11 +59,12 @@ public class EntityManagerImpl extends AbstractEntityManagerImpl implements Sess
public EntityManagerImpl(
EntityManagerFactoryImpl entityManagerFactory,
PersistenceContextType pcType,
SynchronizationType synchronizationType,
PersistenceUnitTransactionType transactionType,
boolean discardOnClose,
Class sessionInterceptorClass,
Map properties) {
super( entityManagerFactory, pcType, transactionType, properties );
super( entityManagerFactory, pcType, synchronizationType, transactionType, properties );
this.open = true;
this.discardOnClose = discardOnClose;
Object localSessionInterceptor = null;
@ -109,10 +111,10 @@ public class EntityManagerImpl extends AbstractEntityManagerImpl implements Sess
sessionBuilder.interceptor( interceptor );
}
catch (InstantiationException e) {
throw new PersistenceException("Unable to instanciate session interceptor: " + sessionInterceptorClass, e);
throw new PersistenceException("Unable to instantiate session interceptor: " + sessionInterceptorClass, e);
}
catch (IllegalAccessException e) {
throw new PersistenceException("Unable to instanciate session interceptor: " + sessionInterceptorClass, e);
throw new PersistenceException("Unable to instantiate session interceptor: " + sessionInterceptorClass, e);
}
catch (ClassCastException e) {
throw new PersistenceException("Session interceptor does not implement Interceptor: " + sessionInterceptorClass, e);

View File

@ -42,6 +42,7 @@ import javax.persistence.PessimisticLockScope;
import javax.persistence.Query;
import javax.persistence.QueryTimeoutException;
import javax.persistence.StoredProcedureQuery;
import javax.persistence.SynchronizationType;
import javax.persistence.TransactionRequiredException;
import javax.persistence.Tuple;
import javax.persistence.TupleElement;
@ -156,6 +157,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
private EntityManagerFactoryImpl entityManagerFactory;
protected transient TransactionImpl tx = new TransactionImpl( this );
protected PersistenceContextType persistenceContextType;
private SynchronizationType synchronizationType;
private PersistenceUnitTransactionType transactionType;
private Map<String, Object> properties;
private LockOptions lockOptions;
@ -163,10 +165,12 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
protected AbstractEntityManagerImpl(
EntityManagerFactoryImpl entityManagerFactory,
PersistenceContextType type,
SynchronizationType synchronizationType,
PersistenceUnitTransactionType transactionType,
Map properties) {
this.entityManagerFactory = entityManagerFactory;
this.persistenceContextType = type;
this.synchronizationType = synchronizationType;
this.transactionType = transactionType;
this.lockOptions = new LockOptions();
@ -181,13 +185,29 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
}
}
// protected PersistenceUnitTransactionType transactionType() {
// return transactionType;
// }
//
// protected SynchronizationType synchronizationType() {
// return synchronizationType;
// }
//
// public boolean shouldAutoJoinTransactions() {
// // the Session should auto join only if using non-JTA transactions or if the synchronization type
// // was specified as SYNCHRONIZED
// return transactionType != PersistenceUnitTransactionType.JTA
// || synchronizationType == SynchronizationType.SYNCHRONIZED;
// }
public PersistenceUnitTransactionType getTransactionType() {
return transactionType;
}
protected void postInit() {
//register in Sync if needed
if ( PersistenceUnitTransactionType.JTA.equals( transactionType ) ) {
if ( transactionType == PersistenceUnitTransactionType.JTA
&& synchronizationType == SynchronizationType.SYNCHRONIZED ) {
joinTransaction( false );
}

View File

@ -0,0 +1,192 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.test.transaction;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.SynchronizationType;
import javax.persistence.TransactionRequiredException;
import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.CriteriaUpdate;
import javax.persistence.criteria.Root;
import java.util.Map;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.ejb.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.transaction.internal.jta.CMTTransaction;
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
import org.hibernate.jpa.AvailableSettings;
import org.junit.Test;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.jta.TestingJtaBootstrap;
import org.hibernate.testing.jta.TestingJtaPlatformImpl;
import org.hibernate.testing.junit4.ExtraAssertions;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* Tests of the JPA 2.1 added {@link SynchronizationType} handling. {@link SynchronizationType#SYNCHRONIZED} is
* the same as 2.0 behavior, so we do not explicitly test for that ({@link TransactionJoiningTest} handles it).
* Tests here specifically test the {@link SynchronizationType#UNSYNCHRONIZED} behavior
*
* @author Steve Ebersole
*/
@TestForIssue( jiraKey = "HHH-7451" )
public class SynchronizationTypeTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected void addConfigOptions(Map options) {
super.addConfigOptions( options );
TestingJtaBootstrap.prepare( options );
options.put( AvailableSettings.TRANSACTION_TYPE, "JTA" );
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { Book.class };
}
@Test
public void testUnSynchronizedExplicitJoinHandling() throws Exception {
// JPA 2.1 adds this notion allowing to open an EM using a specified "SynchronizationType".
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
EntityManager entityManager = entityManagerFactory().createEntityManager( SynchronizationType.UNSYNCHRONIZED, null );
TransactionJoinHandlingChecker.validateExplicitJoiningHandling( entityManager );
}
@Test
public void testImplicitJoining() 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
assertFalse( "setup problem", JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
assertTrue( "setup problem", JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
EntityManager entityManager = entityManagerFactory().createEntityManager( SynchronizationType.UNSYNCHRONIZED, null );
SessionImplementor session = entityManager.unwrap( SessionImplementor.class );
Transaction hibernateTransaction = ( (Session) session ).getTransaction();
ExtraAssertions.assertTyping( CMTTransaction.class, hibernateTransaction );
assertFalse( "EM was auto joined on creation", session.getTransactionCoordinator().isSynchronizationRegistered() );
assertFalse( "EM was auto joined on creation", hibernateTransaction.isParticipating() );
session.getFlushMode();
assertFalse( session.getTransactionCoordinator().isSynchronizationRegistered() );
assertFalse( hibernateTransaction.isParticipating() );
entityManager.joinTransaction();
assertTrue( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
assertTrue( hibernateTransaction.isActive() );
assertTrue( session.getTransactionCoordinator().isSynchronizationRegistered() );
assertTrue( hibernateTransaction.isParticipating() );
assertTrue( entityManager.isOpen() );
assertTrue( session.isOpen() );
entityManager.close();
assertFalse( entityManager.isOpen() );
assertTrue( session.isOpen() );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() );
}
@Test
public void testDisallowedOperations() throws Exception {
// test calling operations that are disallowed while a UNSYNCHRONIZED persistence context is not
// yet joined/enlisted
assertFalse( "setup problem", JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
assertTrue(
"setup problem", JtaStatusHelper.isActive(
TestingJtaPlatformImpl.INSTANCE
.getTransactionManager()
)
);
EntityManager entityManager = entityManagerFactory().createEntityManager( SynchronizationType.UNSYNCHRONIZED, null );
// explicit flushing
try {
entityManager.flush();
fail( "Expecting flush() call to fail" );
}
catch (TransactionRequiredException expected) {
}
// bulk operations
try {
entityManager.createQuery( "delete Book" ).executeUpdate();
fail( "Expecting executeUpdate() call to fail" );
}
catch (TransactionRequiredException expected) {
}
try {
entityManager.createQuery( "update Book set name = null" ).executeUpdate();
fail( "Expecting executeUpdate() call to fail" );
}
catch (TransactionRequiredException expected) {
}
try {
CriteriaDelete<Book> deleteCriteria = entityManager.getCriteriaBuilder().createCriteriaDelete( Book.class );
deleteCriteria.from( Book.class );
entityManager.createQuery( deleteCriteria ).executeUpdate();
fail( "Expecting executeUpdate() call to fail" );
}
catch (TransactionRequiredException expected) {
}
try {
CriteriaUpdate<Book> updateCriteria = entityManager.getCriteriaBuilder().createCriteriaUpdate( Book.class );
updateCriteria.from( Book.class );
updateCriteria.set( Book_.name, (String) null );
entityManager.createQuery( updateCriteria ).executeUpdate();
fail( "Expecting executeUpdate() call to fail" );
}
catch (TransactionRequiredException expected) {
}
try {
entityManager.createQuery( "select b from Book b" )
.setLockMode( LockModeType.PESSIMISTIC_WRITE )
.getResultList();
fail( "Expecting attempted pessimistic lock query to fail" );
}
catch (TransactionRequiredException expected) {
}
entityManager.close();
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().rollback();
}
}

View File

@ -0,0 +1,85 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.ejb.test.transaction;
import javax.persistence.EntityManager;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.transaction.internal.jta.CMTTransaction;
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
import org.hibernate.testing.jta.TestingJtaPlatformImpl;
import org.hibernate.testing.junit4.ExtraAssertions;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* Helper for centralized transaction join checking
*
* @author Steve Ebersole
*/
public class TransactionJoinHandlingChecker {
static void validateExplicitJoiningHandling(EntityManager entityManager) throws Exception {
SessionImplementor session = entityManager.unwrap( SessionImplementor.class );
assertFalse( session.getTransactionCoordinator().isSynchronizationRegistered() );
Transaction hibernateTransaction = ((Session) session).getTransaction();
ExtraAssertions.assertTyping( CMTTransaction.class, hibernateTransaction );
assertFalse( hibernateTransaction.isParticipating() );
session.getFlushMode();
assertFalse( session.getTransactionCoordinator().isSynchronizationRegistered() );
assertFalse( hibernateTransaction.isParticipating() );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
assertTrue( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
assertTrue( hibernateTransaction.isActive() );
assertFalse( hibernateTransaction.isParticipating() );
assertFalse( session.getTransactionCoordinator().isSynchronizationRegistered() );
session.getFlushMode();
assertTrue( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
assertTrue( hibernateTransaction.isActive() );
assertFalse( session.getTransactionCoordinator().isSynchronizationRegistered() );
assertFalse( hibernateTransaction.isParticipating() );
entityManager.joinTransaction();
assertTrue( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
assertTrue( hibernateTransaction.isActive() );
assertTrue( session.getTransactionCoordinator().isSynchronizationRegistered() );
assertTrue( hibernateTransaction.isParticipating() );
assertTrue( entityManager.isOpen() );
assertTrue( session.isOpen() );
entityManager.close();
assertFalse( entityManager.isOpen() );
assertTrue( session.isOpen() );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() );
}
}

View File

@ -23,19 +23,20 @@
*/
package org.hibernate.ejb.test.transaction;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.transaction.Synchronization;
import org.junit.Test;
import java.util.Map;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.ejb.AvailableSettings;
import org.hibernate.ejb.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.transaction.internal.jta.CMTTransaction;
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
import org.hibernate.jpa.AvailableSettings;
import org.junit.Test;
import org.hibernate.testing.jta.TestingJtaBootstrap;
import org.hibernate.testing.jta.TestingJtaPlatformImpl;
@ -60,47 +61,13 @@ public class TransactionJoiningTest extends BaseEntityManagerFunctionalTestCase
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
EntityManager entityManager = entityManagerFactory().createEntityManager();
SessionImplementor session = entityManager.unwrap( SessionImplementor.class );
assertFalse( session.getTransactionCoordinator().isSynchronizationRegistered() );
Transaction hibernateTransaction = ( (Session) session ).getTransaction();
assertTrue( CMTTransaction.class.isInstance( hibernateTransaction ) );
assertFalse( hibernateTransaction.isParticipating() );
session.getFlushMode();
assertFalse( session.getTransactionCoordinator().isSynchronizationRegistered() );
assertFalse( hibernateTransaction.isParticipating() );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
assertTrue( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
assertTrue( hibernateTransaction.isActive() );
assertFalse( hibernateTransaction.isParticipating() );
assertFalse( session.getTransactionCoordinator().isSynchronizationRegistered() );
session.getFlushMode();
assertTrue( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
assertTrue( hibernateTransaction.isActive() );
assertFalse( session.getTransactionCoordinator().isSynchronizationRegistered() );
assertFalse( hibernateTransaction.isParticipating() );
entityManager.joinTransaction();
assertTrue( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
assertTrue( hibernateTransaction.isActive() );
assertTrue( session.getTransactionCoordinator().isSynchronizationRegistered() );
assertTrue( hibernateTransaction.isParticipating() );
assertTrue( entityManager.isOpen() );
assertTrue( session.isOpen() );
entityManager.close();
assertFalse( entityManager.isOpen() );
assertTrue( session.isOpen() );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
assertFalse( entityManager.isOpen() );
assertFalse( session.isOpen() );
TransactionJoinHandlingChecker.validateExplicitJoiningHandling( entityManager );
}
@Test
public void testImplicitJoining() throws Exception {
// here the transaction is started before the EM is opened...
assertFalse( JtaStatusHelper.isActive( TestingJtaPlatformImpl.INSTANCE.getTransactionManager() ) );
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
@ -171,5 +138,4 @@ public class TransactionJoiningTest extends BaseEntityManagerFunctionalTestCase
);
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
}
}