Let Hibernate configure the transaction manager on WebSphere
Closes gh-8926
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.boot.autoconfigure.orm.jpa;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -75,14 +76,6 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration {
|
||||
"org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform",
|
||||
"org.hibernate.service.jta.platform.internal.NoJtaPlatform" };
|
||||
|
||||
/**
|
||||
* {@code WebSphereExtendedJtaPlatform} implementations for various Hibernate
|
||||
* versions.
|
||||
*/
|
||||
private static final String[] WEBSPHERE_JTA_PLATFORM_CLASSES = {
|
||||
"org.hibernate.engine.transaction.jta.platform.internal.WebSphereExtendedJtaPlatform",
|
||||
"org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform" };
|
||||
|
||||
private final HibernateProperties hibernateProperties;
|
||||
|
||||
private final HibernateDefaultDdlAutoProvider defaultDdlAutoProvider;
|
||||
@@ -157,20 +150,15 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration {
|
||||
private void configureJtaPlatform(Map<String, Object> vendorProperties)
|
||||
throws LinkageError {
|
||||
JtaTransactionManager jtaTransactionManager = getJtaTransactionManager();
|
||||
if (jtaTransactionManager != null) {
|
||||
if (runningOnWebSphere()) {
|
||||
// We can never use SpringJtaPlatform on WebSphere as
|
||||
// WebSphereUowTransactionManager has a null TransactionManager
|
||||
// which will cause Hibernate to NPE
|
||||
configureWebSphereTransactionPlatform(vendorProperties);
|
||||
}
|
||||
else {
|
||||
configureSpringJtaPlatform(vendorProperties, jtaTransactionManager);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Make sure Hibernate doesn't attempt to auto-detect a JTA platform
|
||||
if (jtaTransactionManager == null) {
|
||||
vendorProperties.put(JTA_PLATFORM, getNoJtaPlatformManager());
|
||||
}
|
||||
// As of Hibernate 5.2, Hibernate can fully integrate with the WebSphere
|
||||
// transaction manager on its own.
|
||||
else if (!runningOnWebSphere()) {
|
||||
configureSpringJtaPlatform(vendorProperties, jtaTransactionManager);
|
||||
}
|
||||
}
|
||||
|
||||
private void configureProviderDisablesAutocommit(
|
||||
@@ -193,15 +181,6 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration {
|
||||
getClass().getClassLoader());
|
||||
}
|
||||
|
||||
private void configureWebSphereTransactionPlatform(
|
||||
Map<String, Object> vendorProperties) {
|
||||
vendorProperties.put(JTA_PLATFORM, getWebSphereJtaPlatformManager());
|
||||
}
|
||||
|
||||
private Object getWebSphereJtaPlatformManager() {
|
||||
return getJtaPlatformManager(WEBSPHERE_JTA_PLATFORM_CLASSES);
|
||||
}
|
||||
|
||||
private void configureSpringJtaPlatform(Map<String, Object> vendorProperties,
|
||||
JtaTransactionManager jtaTransactionManager) {
|
||||
try {
|
||||
@@ -233,11 +212,7 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration {
|
||||
}
|
||||
|
||||
private Object getNoJtaPlatformManager() {
|
||||
return getJtaPlatformManager(NO_JTA_PLATFORM_CLASSES);
|
||||
}
|
||||
|
||||
private Object getJtaPlatformManager(String[] candidates) {
|
||||
for (String candidate : candidates) {
|
||||
for (String candidate : NO_JTA_PLATFORM_CLASSES) {
|
||||
try {
|
||||
return Class.forName(candidate).newInstance();
|
||||
}
|
||||
@@ -245,7 +220,8 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration {
|
||||
// Continue searching
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Could not configure JTA platform");
|
||||
throw new IllegalStateException("No available JtaPlatform candidates amongst"
|
||||
+ Arrays.toString(NO_JTA_PLATFORM_CLASSES));
|
||||
}
|
||||
|
||||
private static class NamingStrategiesHibernatePropertiesCustomizer
|
||||
|
||||
@@ -35,7 +35,9 @@ import javax.transaction.UserTransaction;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
|
||||
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
|
||||
import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform;
|
||||
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
|
||||
import org.hibernate.internal.SessionFactoryImpl;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
@@ -52,6 +54,8 @@ import org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfigurati
|
||||
import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy;
|
||||
import org.springframework.boot.orm.jpa.hibernate.SpringJtaPlatform;
|
||||
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
@@ -148,13 +152,7 @@ public class HibernateJpaAutoConfigurationTests
|
||||
public void jtaDefaultPlatform() {
|
||||
contextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(JtaAutoConfiguration.class))
|
||||
.run((context) -> {
|
||||
Map<String, Object> jpaPropertyMap = context
|
||||
.getBean(LocalContainerEntityManagerFactoryBean.class)
|
||||
.getJpaPropertyMap();
|
||||
assertThat(jpaPropertyMap.get("hibernate.transaction.jta.platform"))
|
||||
.isInstanceOf(SpringJtaPlatform.class);
|
||||
});
|
||||
.run(assertJtaPlatform(SpringJtaPlatform.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -164,14 +162,23 @@ public class HibernateJpaAutoConfigurationTests
|
||||
"spring.jpa.properties.hibernate.transaction.jta.platform:"
|
||||
+ TestJtaPlatform.class.getName())
|
||||
.withConfiguration(AutoConfigurations.of(JtaAutoConfiguration.class))
|
||||
.run((context) -> {
|
||||
Map<String, Object> jpaPropertyMap = context
|
||||
.getBean(LocalContainerEntityManagerFactoryBean.class)
|
||||
.getJpaPropertyMap();
|
||||
assertThat((String) jpaPropertyMap
|
||||
.get("hibernate.transaction.jta.platform"))
|
||||
.isEqualTo(TestJtaPlatform.class.getName());
|
||||
});
|
||||
.run(assertJtaPlatform(TestJtaPlatform.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jtaNotUsedByTheApplication() {
|
||||
contextRunner().run(assertJtaPlatform(NoJtaPlatform.class));
|
||||
}
|
||||
|
||||
private ContextConsumer<AssertableApplicationContext> assertJtaPlatform(
|
||||
Class<? extends JtaPlatform> expectedType) {
|
||||
return (context) -> {
|
||||
SessionFactoryImpl sessionFactory = context
|
||||
.getBean(LocalContainerEntityManagerFactoryBean.class)
|
||||
.getNativeEntityManagerFactory().unwrap(SessionFactoryImpl.class);
|
||||
assertThat(sessionFactory.getServiceRegistry().getService(JtaPlatform.class))
|
||||
.isInstanceOf(expectedType);
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user