HHH-7451 - Integrate Draft 7 of the JPA 2.1 spec : SynchronizationType
This commit is contained in:
parent
f8d06216e5
commit
6a65c3e7e6
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ) );
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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() );
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue