HHH-12929 - Add AtomikosJtaPlatform implementation

This commit is contained in:
Vlad Mihalcea 2018-08-29 13:07:34 +03:00
parent 04b3230e0f
commit 440a2ef490
7 changed files with 156 additions and 0 deletions

View File

@ -71,6 +71,7 @@ Hibernate tries to discover the `JtaPlatform` it should use through the use of a
If that resolution does not work, or if you wish to provide a custom implementation you will need to specify the `hibernate.transaction.jta.platform` setting.
Hibernate provides many implementations of the `JtaPlatform` contract, all with short names:
`Atomikos`:: `JtaPlatform` for Atomikos.
`Borland`:: `JtaPlatform` for the Borland Enterprise Server.
`Bitronix`:: `JtaPlatform` for Bitronix.
`JBossAS`:: `JtaPlatform` for Arjuna/JBossTransactions/Narayana when used within the JBoss/WildFly Application Server.

View File

@ -136,6 +136,9 @@ ext {
agroal_api: "io.agroal:agroal-api:0.4",
agroal_pool: "io.agroal:agroal-pool:0.4",
atomikos: "com.atomikos:transactions:4.0.6",
atomikos_jta: "com.atomikos:transactions-jta:4.0.6",
cdi: "javax.enterprise:cdi-api:${cdiVersion}",
weld: "org.jboss.weld.se:weld-se-shaded:${weldVersion}",

View File

@ -90,6 +90,8 @@ dependencies {
testRuntime( libraries.javassist )
testRuntime( libraries.byteBuddy )
testRuntime( libraries.weld )
testRuntime( libraries.atomikos )
testRuntime( libraries.atomikos_jta )
testRuntime(libraries.wildfly_transaction_client)
testCompile( project( ':hibernate-jpamodelgen' ) )

View File

@ -70,6 +70,7 @@ import org.hibernate.dialect.SybaseASE15Dialect;
import org.hibernate.dialect.SybaseAnywhereDialect;
import org.hibernate.dialect.TeradataDialect;
import org.hibernate.dialect.TimesTenDialect;
import org.hibernate.engine.transaction.jta.platform.internal.AtomikosJtaPlatform;
import org.hibernate.engine.transaction.jta.platform.internal.BitronixJtaPlatform;
import org.hibernate.engine.transaction.jta.platform.internal.BorlandEnterpriseServerJtaPlatform;
import org.hibernate.engine.transaction.jta.platform.internal.JBossAppServerJtaPlatform;
@ -252,6 +253,13 @@ public class StrategySelectorBuilder {
}
private void addJtaPlatforms(StrategySelectorImpl strategySelector) {
addJtaPlatforms(
strategySelector,
AtomikosJtaPlatform.class,
"Atomikos",
"org.hibernate.service.jta.platform.internal.AtomikosJtaPlatform"
);
addJtaPlatforms(
strategySelector,
BorlandEnterpriseServerJtaPlatform.class,

View File

@ -0,0 +1,36 @@
/*
* 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.engine.transaction.jta.platform.internal;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatformException;
/**
* @author Vlad Mihalcea
*/
public class AtomikosJtaPlatform extends AbstractJtaPlatform {
public static final String TM_CLASS_NAME = "com.atomikos.icatch.jta.UserTransactionManager";
@Override
protected TransactionManager locateTransactionManager() {
try {
Class transactionManagerClass = serviceRegistry().getService( ClassLoaderService.class ).classForName( TM_CLASS_NAME );
return (TransactionManager) transactionManagerClass.newInstance();
}
catch (Exception e) {
throw new JtaPlatformException( "Could not instantiate Atomikos TransactionManager", e );
}
}
@Override
protected UserTransaction locateUserTransaction() {
return (UserTransaction) jndiService().locate( "java:comp/UserTransaction" );
}
}

View File

@ -82,6 +82,14 @@ public class StandardJtaPlatformResolver implements JtaPlatformResolver {
catch (ClassLoadingException ignore) {
}
// Atomikos ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
try {
classLoaderService.classForName( AtomikosJtaPlatform.TM_CLASS_NAME );
return new AtomikosJtaPlatform();
}
catch (ClassLoadingException ignore) {
}
// Bitronix ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
try {
classLoaderService.classForName( BitronixJtaPlatform.TM_CLASS_NAME );

View File

@ -0,0 +1,98 @@
/*
* 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.lazyload;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.transaction.jta.platform.internal.AtomikosJtaPlatform;
import org.hibernate.persister.entity.CustomSqlSchemaResolvingTest;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.jta.TestingJtaBootstrap;
import org.hibernate.testing.jta.TestingJtaPlatformImpl;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
/**
* @author Vlad Mihalcea
*/
public class AtomikosJtaLazyLoadingTest
extends BaseCoreFunctionalTestCase {
private static final int CHILDREN_SIZE = 3;
private Long parentID;
private Long lastChildID;
protected void configure(Configuration cfg) {
super.configure( cfg );
cfg.setProperty( Environment.ENABLE_LAZY_LOAD_NO_TRANS, "true" );
TestingJtaBootstrap.prepare( cfg.getProperties() );
cfg.setProperty( AvailableSettings.JTA_PLATFORM, "Atomikos" );
}
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Parent.class,
Child.class
};
}
protected void prepareTest()
throws Exception {
doInHibernate( this::sessionFactory, session -> {
Parent p = new Parent();
for ( int i = 0; i < CHILDREN_SIZE; i++ ) {
final Child child = p.makeChild();
session.persist( child );
lastChildID = child.getId();
}
session.persist( p );
parentID = p.getId();
} );
}
@Test
@TestForIssue(jiraKey = "HHH-7971")
public void testLazyCollectionLoadingAfterEndTransaction() {
Parent loadedParent = doInHibernate( this::sessionFactory, session -> {
return session.load( Parent.class, parentID );
} );
assertFalse( Hibernate.isInitialized( loadedParent.getChildren() ) );
int i = 0;
for ( Child child : loadedParent.getChildren() ) {
i++;
assertNotNull( child );
}
assertEquals( CHILDREN_SIZE, i );
Child loadedChild = doInHibernate( this::sessionFactory, session -> {
return session.load( Child.class, lastChildID );
} );
Parent p = loadedChild.getParent();
int j = 0;
for ( Child child : p.getChildren() ) {
j++;
assertNotNull( child );
}
assertEquals( CHILDREN_SIZE, j );
}
}