diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.java index 5141bbf609..d9a6433ab4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.java @@ -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 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 vendorProperties) { - vendorProperties.put(JTA_PLATFORM, getWebSphereJtaPlatformManager()); - } - - private Object getWebSphereJtaPlatformManager() { - return getJtaPlatformManager(WEBSPHERE_JTA_PLATFORM_CLASSES); - } - private void configureSpringJtaPlatform(Map 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 diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java index c748c9c79d..8bdf09c03e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java @@ -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 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 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 assertJtaPlatform( + Class expectedType) { + return (context) -> { + SessionFactoryImpl sessionFactory = context + .getBean(LocalContainerEntityManagerFactoryBean.class) + .getNativeEntityManagerFactory().unwrap(SessionFactoryImpl.class); + assertThat(sessionFactory.getServiceRegistry().getService(JtaPlatform.class)) + .isInstanceOf(expectedType); + }; } @Test