HHH-12139 - Allow Hibernate's Transaction act like JPA's EntityTransaction

This commit is contained in:
Steve Ebersole 2017-11-29 21:09:45 -06:00
parent 6ba328e7a0
commit f669c4bcdf
18 changed files with 584 additions and 36 deletions

View File

@ -19,6 +19,7 @@ import org.hibernate.cache.spi.QueryCacheFactory;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.jpa.JpaCompliance;
import org.hibernate.loader.BatchFetchStyle;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode;
@ -718,6 +719,28 @@ public interface SessionFactoryBuilder {
*/
SessionFactoryBuilder enableReleaseResourcesOnCloseEnabled(boolean enable);
/**
* @see JpaCompliance#isJpaQueryComplianceEnabled()
*/
SessionFactoryBuilder enableJpaQueryCompliance(boolean enabled);
/**
* @see JpaCompliance#isJpaTransactionComplianceEnabled()
*/
SessionFactoryBuilder enableJpaTransactionCompliance(boolean enabled);
/**
* @see JpaCompliance#isJpaListComplianceEnabled()
*/
SessionFactoryBuilder enableJpaListCompliance(boolean enabled);
/**
* @see JpaCompliance#isJpaClosedComplianceEnabled()
*/
SessionFactoryBuilder enableJpaClosedCompliance(boolean enabled);
/**
* Allows unwrapping this builder as another, more specific type.
*

View File

@ -52,6 +52,8 @@ import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.internal.SessionFactoryImpl;
import org.hibernate.internal.log.DeprecationLogger;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.jpa.JpaCompliance;
import org.hibernate.jpa.spi.JpaComplianceImpl;
import org.hibernate.loader.BatchFetchStyle;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.query.criteria.LiteralHandlingMode;
@ -502,6 +504,30 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
return this;
}
@Override
public SessionFactoryBuilder enableJpaQueryCompliance(boolean enabled) {
this.options.jpaCompliance.setQueryCompliance( enabled );
return this;
}
@Override
public SessionFactoryBuilder enableJpaTransactionCompliance(boolean enabled) {
this.options.jpaCompliance.setTransactionCompliance( enabled );
return this;
}
@Override
public SessionFactoryBuilder enableJpaListCompliance(boolean enabled) {
this.options.jpaCompliance.setListCompliance( enabled );
return this;
}
@Override
public SessionFactoryBuilder enableJpaClosedCompliance(boolean enabled) {
this.options.jpaCompliance.setClosedCompliance( enabled );
return this;
}
@Override
@SuppressWarnings("unchecked")
public <T extends SessionFactoryBuilder> T unwrap(Class<T> type) {
@ -636,6 +662,8 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
private Map<String, SQLFunction> sqlFunctions;
private JpaComplianceImpl jpaCompliance;
public SessionFactoryOptionsStateStandardImpl(StandardServiceRegistry serviceRegistry) {
this.serviceRegistry = serviceRegistry;
@ -855,6 +883,9 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
configurationSettings,
false
);
// added the boolean parameter in case we want to define some form of "all" as discussed
this.jpaCompliance = new JpaComplianceImpl( configurationSettings, false );
}
private static Interceptor determineInterceptor(Map configurationSettings, StrategySelector strategySelector) {
@ -996,6 +1027,7 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
return allowOutOfTransactionUpdateOperations;
}
@Override
public boolean isReleaseResourcesOnCloseEnabled() {
return releaseResourcesOnCloseEnabled;
@ -1313,6 +1345,11 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
public boolean jdbcStyleParamsZeroBased() {
return this.jdbcStyleParamsZeroBased;
}
@Override
public JpaCompliance getJpaCompliance() {
return jpaCompliance;
}
}
private static Supplier<? extends Interceptor> interceptorSupplier(Class<? extends Interceptor> clazz) {
@ -1354,6 +1391,11 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
return options.releaseResourcesOnCloseEnabled;
}
@Override
public JpaCompliance getJpaCompliance() {
return options.jpaCompliance;
}
@Override
public Object getBeanManagerReference() {
return options.getBeanManagerReference();

View File

@ -24,6 +24,7 @@ import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.internal.log.DeprecationLogger;
import org.hibernate.jpa.JpaCompliance;
import org.hibernate.loader.BatchFetchStyle;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.query.criteria.LiteralHandlingMode;
@ -133,6 +134,7 @@ public class SessionFactoryOptionsImpl implements SessionFactoryOptions {
private boolean queryParametersValidationEnabled;
private LiteralHandlingMode criteriaLiteralHandlingMode;
private boolean jdbcStyleParamsZeroBased;
private final JpaCompliance jpaCompliance;
public SessionFactoryOptionsImpl(SessionFactoryOptionsState state) {
this.serviceRegistry = state.getServiceRegistry();
@ -218,6 +220,8 @@ public class SessionFactoryOptionsImpl implements SessionFactoryOptions {
this.sqlFunctions = state.getCustomSqlFunctionMap();
this.jdbcTimeZone = state.getJdbcTimeZone();
this.jpaCompliance = state.getJpaCompliance();
}
@Override
@ -568,4 +572,9 @@ public class SessionFactoryOptionsImpl implements SessionFactoryOptions {
public boolean jdbcStyleParamsZeroBased() {
return jdbcStyleParamsZeroBased;
}
@Override
public JpaCompliance getJpaCompliance() {
return jpaCompliance;
}
}

View File

@ -24,6 +24,7 @@ import org.hibernate.cfg.BaselineSessionEventsListenerBuilder;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.jpa.JpaCompliance;
import org.hibernate.loader.BatchFetchStyle;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.query.criteria.LiteralHandlingMode;
@ -58,6 +59,8 @@ public interface SessionFactoryOptionsState {
boolean isReleaseResourcesOnCloseEnabled();
JpaCompliance getJpaCompliance();
Object getBeanManagerReference();
Object getValidatorFactoryReference();

View File

@ -389,6 +389,30 @@ public abstract class AbstractDelegatingSessionFactoryBuilder<T extends SessionF
return getThis();
}
@Override
public SessionFactoryBuilder enableJpaQueryCompliance(boolean enabled) {
delegate.enableJpaQueryCompliance( enabled );
return getThis();
}
@Override
public SessionFactoryBuilder enableJpaTransactionCompliance(boolean enabled) {
delegate.enableJpaTransactionCompliance( enabled );
return getThis();
}
@Override
public SessionFactoryBuilder enableJpaListCompliance(boolean enabled) {
delegate.enableJpaListCompliance( enabled );
return getThis();
}
@Override
public SessionFactoryBuilder enableJpaClosedCompliance(boolean enabled) {
delegate.enableJpaClosedCompliance( enabled );
return getThis();
}
@Override
@SuppressWarnings("unchecked")
public <S extends SessionFactoryBuilder> S unwrap(Class<S> type) {

View File

@ -22,6 +22,7 @@ import org.hibernate.cfg.BaselineSessionEventsListenerBuilder;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.jpa.JpaCompliance;
import org.hibernate.loader.BatchFetchStyle;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.query.criteria.LiteralHandlingMode;
@ -400,4 +401,9 @@ public class AbstractDelegatingSessionFactoryOptions implements SessionFactoryOp
public boolean jdbcStyleParamsZeroBased() {
return delegate.jdbcStyleParamsZeroBased();
}
@Override
public JpaCompliance getJpaCompliance() {
return delegate.getJpaCompliance();
}
}

View File

@ -23,6 +23,7 @@ import org.hibernate.cfg.BaselineSessionEventsListenerBuilder;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.jpa.JpaCompliance;
import org.hibernate.loader.BatchFetchStyle;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.query.criteria.LiteralHandlingMode;
@ -250,4 +251,6 @@ public interface SessionFactoryOptions {
}
boolean jdbcStyleParamsZeroBased();
JpaCompliance getJpaCompliance();
}

View File

@ -10,9 +10,11 @@ import java.util.function.Supplier;
import javax.persistence.GeneratedValue;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataBuilder;
import org.hibernate.boot.registry.classloading.internal.TcclLookupPrecedence;
import org.hibernate.internal.log.DeprecationLogger;
import org.hibernate.jpa.JpaCompliance;
import org.hibernate.query.internal.ParameterMetadataImpl;
import org.hibernate.resource.transaction.spi.TransactionCoordinator;
import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder;
@ -1741,4 +1743,51 @@ public interface AvailableSettings {
* `hibernate_sequence` name should disable this setting,
*/
String PREFER_GENERATOR_NAME_AS_DEFAULT_SEQUENCE_NAME = "hibernate.model.generator_name_as_sequence_name";
/**
* Should Hibernate's {@link Transaction} behave as
* defined by the spec for JPA's {@link javax.persistence.EntityTransaction}
* since it extends the JPA one.
*
* @see JpaCompliance#isJpaTransactionComplianceEnabled()
*/
String JPA_TRANSACTION_COMPLIANCE = "hibernate.jpa.compliance.transaction";
/**
* Controls whether Hibernate's handling of {@link javax.persistence.Query}
* (JPQL, Criteria and native-query) should strictly follow the JPA spec.
* Tis includes both in terms of parsing or translating a query as well
* as calls to the {@link javax.persistence.Query} methods throwing spec
* defined exceptions where as Hibernate might not.
*
* Deviations result in an exception if enabled
*
* @see JpaCompliance#isJpaQueryComplianceEnabled()
*/
String JPA_QUERY_COMPLIANCE = "hibernate.jpa.compliance.query";
/**
* Controls whether Hibernate should recognize what it considers a "bag"
* ({@link org.hibernate.collection.internal.PersistentBag}) as a List
* ({@link org.hibernate.collection.internal.PersistentList}) or as a bag.
*
* If enabled, we will recognize it as a List where {@link @{@link javax.persistence.OrderColumn}}
* is just missing (and its defaults will apply).
*
* @see JpaCompliance#isJpaListComplianceEnabled()
*/
String JPA_LIST_COMPLIANCE = "hibernate.jpa.compliance.list";
/**
* JPA defines specific exceptions on specific methods when called on
* {@link javax.persistence.EntityManager} and {@link javax.persistence.EntityManagerFactory}
* when those objects have been closed. This setting controls
* whether the spec defined behavior or Hibernate's behavior will be used.
*
* If enabled Hibernate will operate in the JPA specified way throwing
* exceptions when the spec says it should.
*
* @see JpaCompliance#isJpaClosedComplianceEnabled()
*/
String JPA_CLOSED_COMPLIANCE = "hibernate.jpa.compliance.closed";
}

View File

@ -13,6 +13,7 @@ import org.hibernate.TransactionException;
import org.hibernate.engine.spi.ExceptionConverter;
import org.hibernate.engine.transaction.spi.TransactionImplementor;
import org.hibernate.internal.CoreLogging;
import org.hibernate.jpa.JpaCompliance;
import org.hibernate.resource.transaction.spi.TransactionCoordinator;
import org.hibernate.resource.transaction.spi.TransactionStatus;
@ -29,12 +30,24 @@ public class TransactionImpl implements TransactionImplementor {
private final TransactionCoordinator transactionCoordinator;
private final ExceptionConverter exceptionConverter;
private final JpaCompliance jpaCompliance;
private TransactionDriver transactionDriverControl;
public TransactionImpl(TransactionCoordinator transactionCoordinator, ExceptionConverter exceptionConverter) {
public TransactionImpl(
TransactionCoordinator transactionCoordinator,
ExceptionConverter exceptionConverter,
JpaCompliance jpaCompliance) {
this.transactionCoordinator = transactionCoordinator;
this.exceptionConverter = exceptionConverter;
transactionDriverControl = transactionCoordinator.getTransactionDriverControl();
this.jpaCompliance = jpaCompliance;
this.transactionDriverControl = transactionCoordinator.getTransactionDriverControl();
LOG.debugf(
"On TransactionImpl creation, JpaCompliance#isJpaTransactionComplianceEnabled == %s",
jpaCompliance.isJpaTransactionComplianceEnabled()
);
}
@Override
@ -82,7 +95,14 @@ public class TransactionImpl implements TransactionImplementor {
@Override
public void rollback() {
// todo : may need a "JPA compliant" flag here
if ( jpaCompliance.isJpaTransactionComplianceEnabled() ) {
if ( !isActive() ) {
throw new IllegalStateException(
"JPA compliance dictates throwing IllegalStateException when #rollback " +
"is called on non-active transaction"
);
}
}
TransactionStatus status = getStatus();
if ( status == TransactionStatus.ROLLED_BACK || status == TransactionStatus.NOT_ACTIVE ) {
@ -140,11 +160,29 @@ public class TransactionImpl implements TransactionImplementor {
@Override
public void setRollbackOnly() {
if ( jpaCompliance.isJpaTransactionComplianceEnabled() ) {
if ( !isActive() ) {
throw new IllegalStateException(
"JPA compliance dictates throwing IllegalStateException when #setRollbackOnly " +
"is called on non-active transaction"
);
}
}
internalGetTransactionDriverControl().markRollbackOnly();
}
@Override
public boolean getRollbackOnly() {
if ( jpaCompliance.isJpaTransactionComplianceEnabled() ) {
if ( !isActive() ) {
throw new IllegalStateException(
"JPA compliance dictates throwing IllegalStateException when #getRollbackOnly " +
"is called on non-active transaction"
);
}
}
return getStatus() == TransactionStatus.MARKED_ROLLBACK;
}

View File

@ -374,7 +374,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
@Override
public Transaction getTransaction() throws HibernateException {
if ( getFactory().getSessionFactoryOptions().isJpaBootstrap() ) {
if ( getFactory().getSessionFactoryOptions().getJpaCompliance().isJpaTransactionComplianceEnabled() ) {
// JPA requires that we throw IllegalStateException if this is called
// on a JTA EntityManager
if ( getTransactionCoordinator().getTransactionCoordinatorBuilder().isJta() ) {
@ -383,6 +383,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
}
}
}
return accessTransaction();
}
@ -391,7 +392,8 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
if ( this.currentHibernateTransaction == null || this.currentHibernateTransaction.getStatus() != TransactionStatus.ACTIVE ) {
this.currentHibernateTransaction = new TransactionImpl(
getTransactionCoordinator(),
getExceptionConverter()
getExceptionConverter(),
getFactory().getSessionFactoryOptions().getJpaCompliance()
);
}

View File

@ -110,19 +110,32 @@ public final class ConfigurationHelper {
* @return The value.
*/
public static boolean getBoolean(String name, Map values, boolean defaultValue) {
Object value = values.get( name );
final Object raw = values.get( name );
final Boolean value = toBoolean( raw, defaultValue );
if ( value == null ) {
throw new ConfigurationException(
"Could not determine how to handle configuration raw [name=" + name + ", value=" + raw + "] as boolean"
);
}
return value;
}
public static Boolean toBoolean(Object value, boolean defaultValue) {
if ( value == null ) {
return defaultValue;
}
if ( Boolean.class.isInstance( value ) ) {
return ( (Boolean) value ).booleanValue();
return (Boolean) value;
}
if ( String.class.isInstance( value ) ) {
return Boolean.parseBoolean( (String) value );
}
throw new ConfigurationException(
"Could not determine how to handle configuration value [name=" + name + ", value=" + value + "] as boolean"
);
return null;
}
/**

View File

@ -0,0 +1,66 @@
/*
* 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;
import org.hibernate.Transaction;
/**
* Encapsulates settings controlling whether certain aspects of the JPA spec
* should be strictly followed.
*
* @author Steve Ebersole
*/
public interface JpaCompliance {
/**
* Controls whether Hibernate's handling of JPA's
* {@link javax.persistence.Query} (JPQL, Criteria and native-query) should
* strictly follow the JPA spec. This includes both in terms of parsing or
* translating a query as well as calls to the {@link javax.persistence.Query}
* methods throwing spec defined exceptions where as Hibernate might not.
*
* Deviations result in an exception if enabled
*
* @return {@code true} indicates to behave in the spec-defined way
*/
boolean isJpaQueryComplianceEnabled();
/**
* Indicates that Hibernate's {@link Transaction} should behave as
* defined by the spec for JPA's {@link javax.persistence.EntityTransaction}
* since it extends the JPA one.
*
* @return {@code true} indicates to behave in the spec-defined way
*/
boolean isJpaTransactionComplianceEnabled();
/**
* Controls how Hibernate interprets a mapped List without an "order columns"
* specified. Historically Hibernate defines this as a "bag", which is a concept
* JPA does not have.
*
* If enabled, Hibernate will recognize this condition as defining
* a {@link org.hibernate.collection.internal.PersistentList}, otherwise
* Hibernate will treat is as a {@link org.hibernate.collection.internal.PersistentBag}
*
* @return {@code true} indicates to behave in the spec-defined way, interpreting the
* mapping as a "list", rather than a "bag"
*/
boolean isJpaListComplianceEnabled();
/**
*JPA defines specific exceptions on specific methods when called on
* {@link javax.persistence.EntityManager} and {@link javax.persistence.EntityManagerFactory}
* when those objects have been closed. This setting controls
* whether the spec defined behavior or Hibernate's behavior will be used.
*
* If enabled Hibernate will operate in the JPA specified way throwing
* exceptions when the spec says it should with regard to close checking
*
* @return {@code true} indicates to behave in the spec-defined way
*/
boolean isJpaClosedComplianceEnabled();
}

View File

@ -0,0 +1,90 @@
/*
* 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.spi;
import java.util.Map;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.jpa.JpaCompliance;
/**
* @author Steve Ebersole
*/
public class JpaComplianceImpl implements JpaCompliance {
private boolean queryCompliance;
private boolean transactionCompliance;
private boolean listCompliance;
private boolean closedCompliance;
@SuppressWarnings("ConstantConditions")
public JpaComplianceImpl(Map configurationSettings, boolean jpaByDefault) {
final Object legacyQueryCompliance = configurationSettings.get( AvailableSettings.JPAQL_STRICT_COMPLIANCE );
queryCompliance = ConfigurationHelper.getBoolean(
AvailableSettings.JPA_QUERY_COMPLIANCE,
configurationSettings,
legacyQueryCompliance == null ? jpaByDefault : ConfigurationHelper.toBoolean( legacyQueryCompliance, jpaByDefault )
);
transactionCompliance = ConfigurationHelper.getBoolean(
AvailableSettings.JPA_TRANSACTION_COMPLIANCE,
configurationSettings,
jpaByDefault
);
listCompliance = ConfigurationHelper.getBoolean(
AvailableSettings.JPA_LIST_COMPLIANCE,
configurationSettings,
jpaByDefault
);
closedCompliance = ConfigurationHelper.getBoolean(
AvailableSettings.JPA_CLOSED_COMPLIANCE,
configurationSettings,
jpaByDefault
);
}
@Override
public boolean isJpaQueryComplianceEnabled() {
return queryCompliance;
}
@Override
public boolean isJpaTransactionComplianceEnabled() {
return transactionCompliance;
}
@Override
public boolean isJpaListComplianceEnabled() {
return listCompliance;
}
@Override
public boolean isJpaClosedComplianceEnabled() {
return closedCompliance;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Mutators
public void setQueryCompliance(boolean queryCompliance) {
this.queryCompliance = queryCompliance;
}
public void setTransactionCompliance(boolean transactionCompliance) {
this.transactionCompliance = transactionCompliance;
}
public void setListCompliance(boolean listCompliance) {
this.listCompliance = listCompliance;
}
public void setClosedCompliance(boolean closedCompliance) {
this.closedCompliance = closedCompliance;
}
}

View File

@ -23,7 +23,7 @@ public interface TransactionCoordinatorBuilder extends Service {
/**
* Access to options to are specific to each TransactionCoordinator instance
*/
static interface Options {
interface Options {
/**
* Indicates whether an active transaction should be automatically joined. Only relevant
* for JTA-based TransactionCoordinator instances.

View File

@ -0,0 +1,66 @@
/*
* 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;
/**
* @author Steve Ebersole
*/
public class JpaComplianceTestingImpl implements JpaCompliance {
public static JpaCompliance normal() {
return new JpaComplianceTestingImpl();
}
public static JpaCompliance withTransactionCompliance() {
final JpaComplianceTestingImpl compliance = new JpaComplianceTestingImpl();
compliance.transactionCompliance = true;
return compliance;
}
public static JpaCompliance withQueryCompliance() {
final JpaComplianceTestingImpl compliance = new JpaComplianceTestingImpl();
compliance.queryCompliance = true;
return compliance;
}
public static JpaCompliance withListCompliance() {
final JpaComplianceTestingImpl compliance = new JpaComplianceTestingImpl();
compliance.listCompliance = true;
return compliance;
}
public static JpaCompliance withClosedCompliance() {
final JpaComplianceTestingImpl compliance = new JpaComplianceTestingImpl();
compliance.closedCompliance = true;
return compliance;
}
private boolean queryCompliance;
private boolean transactionCompliance;
private boolean listCompliance;
private boolean closedCompliance;
@Override
public boolean isJpaQueryComplianceEnabled() {
return queryCompliance;
}
@Override
public boolean isJpaTransactionComplianceEnabled() {
return transactionCompliance;
}
@Override
public boolean isJpaListComplianceEnabled() {
return listCompliance;
}
@Override
public boolean isJpaClosedComplianceEnabled() {
return closedCompliance;
}
}

View File

@ -0,0 +1,132 @@
/*
* 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.test.jpa.compliance.tck2_2;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil2.inSession;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;
/**
* @author Steve Ebersole
*/
public class EntityTransactionTests extends BaseUnitTestCase {
@Test
public void testGetRollbackOnlyExpectations() {
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder()
.applySetting( AvailableSettings.JPA_TRANSACTION_COMPLIANCE, "true" )
.build();
try {
final SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) new MetadataSources( ssr )
.buildMetadata()
.buildSessionFactory();
try {
inSession(
sessionFactory,
session -> {
final Transaction transaction = session.getTransaction();
assertFalse( transaction.isActive() );
try {
transaction.getRollbackOnly();
fail( "Expecting failure #getRollbackOnly on non-active txn" );
}
catch (IllegalStateException expected) {
}
}
);
}
finally {
sessionFactory.close();
}
}
finally {
StandardServiceRegistryBuilder.destroy( ssr );
}
}
@Test
public void testSetRollbackOnlyExpectations() {
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder()
.applySetting( AvailableSettings.JPA_TRANSACTION_COMPLIANCE, "true" )
.build();
try {
final SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) new MetadataSources( ssr )
.buildMetadata()
.buildSessionFactory();
try {
inSession(
sessionFactory,
session -> {
final Transaction transaction = session.getTransaction();
assertFalse( transaction.isActive() );
try {
transaction.setRollbackOnly();
fail( "Expecting failure #setRollbackOnly on non-active txn" );
}
catch (IllegalStateException expected) {
}
}
);
}
finally {
sessionFactory.close();
}
}
finally {
StandardServiceRegistryBuilder.destroy( ssr );
}
}
@Test
public void testRollbackExpectations() {
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder()
.applySetting( AvailableSettings.JPA_TRANSACTION_COMPLIANCE, "true" )
.build();
try {
final SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) new MetadataSources( ssr )
.buildMetadata()
.buildSessionFactory();
try {
inSession(
sessionFactory,
session -> {
final Transaction transaction = session.getTransaction();
assertFalse( transaction.isActive() );
try {
transaction.rollback();
fail( "Expecting failure #rollback on non-active txn" );
}
catch (IllegalStateException expected) {
}
}
);
}
finally {
sessionFactory.close();
}
}
finally {
StandardServiceRegistryBuilder.destroy( ssr );
}
}
}

View File

@ -9,7 +9,6 @@ package org.hibernate.test.resource.transaction.jdbc;
import org.hibernate.TransactionException;
import org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorBuilderImpl;
import org.hibernate.resource.transaction.spi.TransactionCoordinator;
import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder;
import org.hibernate.resource.transaction.spi.TransactionStatus;
import org.hibernate.test.resource.common.SynchronizationCollectorImpl;
@ -31,12 +30,7 @@ public class BasicJdbcTransactionTests {
final TransactionCoordinator transactionCoordinator = transactionCoordinatorBuilder.buildTransactionCoordinator(
owner,
new TransactionCoordinatorBuilder.Options() {
@Override
public boolean shouldAutoJoinTransaction() {
return false;
}
}
() -> false
);
SynchronizationCollectorImpl sync = new SynchronizationCollectorImpl();
@ -63,12 +57,7 @@ public class BasicJdbcTransactionTests {
final TransactionCoordinator transactionCoordinator = transactionCoordinatorBuilder.buildTransactionCoordinator(
owner,
new TransactionCoordinatorBuilder.Options() {
@Override
public boolean shouldAutoJoinTransaction() {
return false;
}
}
() -> false
);
assertEquals( TransactionStatus.NOT_ACTIVE, transactionCoordinator.getTransactionDriverControl().getStatus() );
@ -98,12 +87,7 @@ public class BasicJdbcTransactionTests {
final TransactionCoordinator transactionCoordinator = transactionCoordinatorBuilder.buildTransactionCoordinator(
owner,
new TransactionCoordinatorBuilder.Options() {
@Override
public boolean shouldAutoJoinTransaction() {
return false;
}
}
() -> false
);
assertEquals( TransactionStatus.NOT_ACTIVE, transactionCoordinator.getTransactionDriverControl().getStatus() );

View File

@ -60,11 +60,6 @@ import org.junit.After;
import org.junit.Test;
import junit.framework.AssertionFailedError;
import org.infinispan.Cache;
import org.infinispan.test.TestingUtil;
import org.jboss.logging.Logger;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@ -339,7 +334,10 @@ public abstract class AbstractRegionAccessStrategyTest<R extends BaseRegion, S e
.buildTransactionCoordinator(txOwner, null);
when(session.getTransactionCoordinator()).thenReturn(txCoord);
when(session.beginTransaction()).then(invocation -> {
Transaction tx = new TransactionImpl(txCoord, session.getExceptionConverter());
Transaction tx = new TransactionImpl(
txCoord,
session.getExceptionConverter(),
session.getFactory().getSessionFactoryOptions().getJpaCompliance() );
tx.begin();
return tx;
});