Commit ac0a22d6 authored by Andy Wilkinson's avatar Andy Wilkinson

Tolerate LCEMFB with null JpaVendorAdapter in JPA auto-config

Closes gh-17935
parent abe3d385
...@@ -58,11 +58,17 @@ class DataSourceInitializedPublisher implements BeanPostProcessor { ...@@ -58,11 +58,17 @@ class DataSourceInitializedPublisher implements BeanPostProcessor {
private HibernateProperties hibernateProperties; private HibernateProperties hibernateProperties;
private DataSourceSchemaCreatedPublisher schemaCreatedPublisher;
@Override @Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof LocalContainerEntityManagerFactoryBean) { if (bean instanceof LocalContainerEntityManagerFactoryBean) {
LocalContainerEntityManagerFactoryBean factory = (LocalContainerEntityManagerFactoryBean) bean; LocalContainerEntityManagerFactoryBean factory = (LocalContainerEntityManagerFactoryBean) bean;
factory.setJpaVendorAdapter(new DataSourceSchemaCreatedPublisher(factory)); if (factory.getBootstrapExecutor() != null && factory.getJpaVendorAdapter() != null) {
this.schemaCreatedPublisher = new DataSourceSchemaCreatedPublisher(factory.getBootstrapExecutor(),
factory.getJpaVendorAdapter());
factory.setJpaVendorAdapter(this.schemaCreatedPublisher);
}
} }
return bean; return bean;
} }
...@@ -79,11 +85,9 @@ class DataSourceInitializedPublisher implements BeanPostProcessor { ...@@ -79,11 +85,9 @@ class DataSourceInitializedPublisher implements BeanPostProcessor {
if (bean instanceof HibernateProperties) { if (bean instanceof HibernateProperties) {
this.hibernateProperties = (HibernateProperties) bean; this.hibernateProperties = (HibernateProperties) bean;
} }
if (bean instanceof LocalContainerEntityManagerFactoryBean) { if (bean instanceof LocalContainerEntityManagerFactoryBean && this.schemaCreatedPublisher == null) {
LocalContainerEntityManagerFactoryBean factory = (LocalContainerEntityManagerFactoryBean) bean; LocalContainerEntityManagerFactoryBean factory = (LocalContainerEntityManagerFactoryBean) bean;
if (factory.getBootstrapExecutor() == null) { publishEventIfRequired(factory.getNativeEntityManagerFactory());
publishEventIfRequired(factory.getNativeEntityManagerFactory());
}
} }
return bean; return bean;
} }
...@@ -141,13 +145,14 @@ class DataSourceInitializedPublisher implements BeanPostProcessor { ...@@ -141,13 +145,14 @@ class DataSourceInitializedPublisher implements BeanPostProcessor {
final class DataSourceSchemaCreatedPublisher implements JpaVendorAdapter { final class DataSourceSchemaCreatedPublisher implements JpaVendorAdapter {
private final JpaVendorAdapter delegate; private final AsyncTaskExecutor bootstrapExecutor;
private final LocalContainerEntityManagerFactoryBean factory; private final JpaVendorAdapter delegate;
private DataSourceSchemaCreatedPublisher(LocalContainerEntityManagerFactoryBean factory) { private DataSourceSchemaCreatedPublisher(AsyncTaskExecutor bootstrapExecutor,
this.delegate = factory.getJpaVendorAdapter(); JpaVendorAdapter jpaVendorAdapter) {
this.factory = factory; this.bootstrapExecutor = bootstrapExecutor;
this.delegate = jpaVendorAdapter;
} }
@Override @Override
...@@ -188,9 +193,8 @@ class DataSourceInitializedPublisher implements BeanPostProcessor { ...@@ -188,9 +193,8 @@ class DataSourceInitializedPublisher implements BeanPostProcessor {
@Override @Override
public void postProcessEntityManagerFactory(EntityManagerFactory emf) { public void postProcessEntityManagerFactory(EntityManagerFactory emf) {
this.delegate.postProcessEntityManagerFactory(emf); this.delegate.postProcessEntityManagerFactory(emf);
AsyncTaskExecutor bootstrapExecutor = this.factory.getBootstrapExecutor(); if (this.bootstrapExecutor != null) {
if (bootstrapExecutor != null) { this.bootstrapExecutor.execute(() -> DataSourceInitializedPublisher.this.publishEventIfRequired(emf));
bootstrapExecutor.execute(() -> DataSourceInitializedPublisher.this.publishEventIfRequired(emf));
} }
} }
......
...@@ -23,11 +23,13 @@ import java.util.ArrayList; ...@@ -23,11 +23,13 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import javax.transaction.Synchronization; import javax.transaction.Synchronization;
import javax.transaction.Transaction; import javax.transaction.Transaction;
import javax.transaction.TransactionManager; import javax.transaction.TransactionManager;
...@@ -40,6 +42,7 @@ import org.hibernate.cfg.AvailableSettings; ...@@ -40,6 +42,7 @@ import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform; import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform;
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform; import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;
import org.hibernate.internal.SessionFactoryImpl; import org.hibernate.internal.SessionFactoryImpl;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCreationException;
...@@ -359,6 +362,18 @@ public class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigura ...@@ -359,6 +362,18 @@ public class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigura
}); });
} }
@Test
public void whenLocalContanerEntityManagerFactoryBeanHasNoJpaVendorAdapterAutoConfigurationSucceeds() {
contextRunner()
.withUserConfiguration(
TestConfigurationWithLocalContainerEntityManagerFactoryBeanWithNoJpaVendorAdapter.class)
.run((context) -> {
EntityManagerFactory factoryBean = context.getBean(EntityManagerFactory.class);
Map<String, Object> map = factoryBean.getProperties();
assertThat(map.get("configured")).isEqualTo("manually");
});
}
private boolean dataSourceSchemaCreatedEventReceived(EventCapturingApplicationListener listener) { private boolean dataSourceSchemaCreatedEventReceived(EventCapturingApplicationListener listener) {
for (ApplicationEvent event : listener.events) { for (ApplicationEvent event : listener.events) {
if (event instanceof DataSourceSchemaCreatedEvent) { if (event instanceof DataSourceSchemaCreatedEvent) {
...@@ -522,4 +537,23 @@ public class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigura ...@@ -522,4 +537,23 @@ public class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigura
} }
@Configuration
protected static class TestConfigurationWithLocalContainerEntityManagerFactoryBeanWithNoJpaVendorAdapter
extends TestConfiguration {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setPersistenceUnitName("manually-configured");
factoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
Map<String, Object> properties = new HashMap<>();
properties.put("configured", "manually");
properties.put("hibernate.transaction.jta.platform", NoJtaPlatform.INSTANCE);
factoryBean.setJpaPropertyMap(properties);
return factoryBean;
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment