Configure Hibernate with a WAS-specific JtaPlatform when running on WAS
At the time of writing WAS only supports JPA 2.0 which means that Hibernate 4.2 is the latest version that can be used. SpringJtaPlatform is Hibernate 4.3-specific as JtaPlatform’s package changed between Hibernate 4.2 and 4.3. This means that SpringJtaPlatform can’t be used on current versions of WAS. Futhermore, SpringJtaPlatform won’t work on WAS even if we could use Hibernate 4.3 as WAS doesn’t make its TransactionManager available to application code (it’s considered too dangerous for general consumption) and SpringJtaPlatform requires a TransactionManager. This commit updates HibernateJpaAutoConfiguration to always treat WAS as a special case and configure Hibernate with one of its WAS-specific JtaPlatform implementations. Closes gh-2326
This commit is contained in:
parent
2665ef0692
commit
b542aa3de6
|
|
@ -74,6 +74,14 @@ public class HibernateJpaAutoConfiguration 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 WEBSHERE_JTA_PLATFORM_CLASSES[] = {
|
||||
"org.hibernate.engine.transaction.jta.platform.internal.WebSphereExtendedJtaPlatform",
|
||||
"org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform", };
|
||||
|
||||
@Autowired
|
||||
private JpaProperties properties;
|
||||
|
||||
|
|
@ -104,25 +112,14 @@ public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {
|
|||
throws LinkageError {
|
||||
JtaTransactionManager jtaTransactionManager = getJtaTransactionManager();
|
||||
if (jtaTransactionManager != null) {
|
||||
try {
|
||||
vendorProperties.put(JTA_PLATFORM, new SpringJtaPlatform(
|
||||
jtaTransactionManager));
|
||||
if (runningOnWebSphere()) {
|
||||
// We can never use SpringJtaPlatform on WebSphere as
|
||||
// WebSphereUowTransactionManger has a null TransactionManager
|
||||
// which will cause Hibernate to NPE
|
||||
configureWebSphereTransactionPlatform(vendorProperties);
|
||||
}
|
||||
catch (NoClassDefFoundError ex) {
|
||||
// Can happen if Hibernate 4.2 is used (for example on WAS)
|
||||
if (isUsingJndi()) {
|
||||
// Assume that we are not using a stand-alone transaction manager
|
||||
// and Hibernate will use JNDI
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Unable to set Hibernate JTA platform : "
|
||||
+ ex.getMessage());
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Unable to set Hibernate JTA "
|
||||
+ "platform, are you using the correct "
|
||||
+ "version of hibernate?", ex);
|
||||
}
|
||||
else {
|
||||
configureSpringJtaPlatform(vendorProperties, jtaTransactionManager);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -130,6 +127,56 @@ public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean runningOnWebSphere() {
|
||||
return ClassUtils.isPresent(
|
||||
"com.ibm.websphere.jtaextensions.ExtendedJTATransaction", getClass()
|
||||
.getClassLoader());
|
||||
}
|
||||
|
||||
private void configureWebSphereTransactionPlatform(
|
||||
Map<String, Object> vendorProperties) {
|
||||
vendorProperties.put(JTA_PLATFORM, getWebSphereJtaPlatformManager());
|
||||
}
|
||||
|
||||
private Object getWebSphereJtaPlatformManager() {
|
||||
return getJtaPlatformManager(WEBSHERE_JTA_PLATFORM_CLASSES);
|
||||
}
|
||||
|
||||
private Object getJtaPlatformManager(String[] candidates) {
|
||||
for (String candidate : candidates) {
|
||||
try {
|
||||
return Class.forName(candidate).newInstance();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Continue searching
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Could not configure JTA platform");
|
||||
}
|
||||
|
||||
private void configureSpringJtaPlatform(Map<String, Object> vendorProperties,
|
||||
JtaTransactionManager jtaTransactionManager) {
|
||||
try {
|
||||
vendorProperties.put(JTA_PLATFORM, new SpringJtaPlatform(
|
||||
jtaTransactionManager));
|
||||
}
|
||||
catch (NoClassDefFoundError ex) {
|
||||
// Can happen if Hibernate 4.2 is used
|
||||
if (isUsingJndi()) {
|
||||
// Assume that Hibernate will use JNDI
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Unable to set Hibernate JTA platform : "
|
||||
+ ex.getMessage());
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Unable to set Hibernate JTA "
|
||||
+ "platform, are you using the correct "
|
||||
+ "version of Hibernate?", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isUsingJndi() {
|
||||
try {
|
||||
return JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable();
|
||||
|
|
@ -140,15 +187,7 @@ public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {
|
|||
}
|
||||
|
||||
private Object getNoJtaPlatformManager() {
|
||||
for (String noJtaPlatformClass : NO_JTA_PLATFORM_CLASSES) {
|
||||
try {
|
||||
return Class.forName(noJtaPlatformClass).newInstance();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Continue searching
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Could not configure JTA platform");
|
||||
return getJtaPlatformManager(NO_JTA_PLATFORM_CLASSES);
|
||||
}
|
||||
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE + 20)
|
||||
|
|
|
|||
|
|
@ -32,11 +32,13 @@ import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
|
|||
import org.springframework.boot.autoconfigure.jta.JtaAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jta.JtaProperties;
|
||||
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
|
||||
import org.springframework.boot.orm.jpa.hibernate.SpringJtaPlatform;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
|
@ -148,6 +150,17 @@ public class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigura
|
|||
this.context.refresh();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultJtaPlatform() throws Exception {
|
||||
this.context.register(JtaProperties.class, JtaAutoConfiguration.class);
|
||||
setupTestConfiguration();
|
||||
this.context.refresh();
|
||||
Map<String, Object> jpaPropertyMap = this.context.getBean(
|
||||
LocalContainerEntityManagerFactoryBean.class).getJpaPropertyMap();
|
||||
assertThat(jpaPropertyMap.get("hibernate.transaction.jta.platform"),
|
||||
instanceOf(SpringJtaPlatform.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomJtaPlatform() throws Exception {
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
|
|
|
|||
Loading…
Reference in New Issue