Commit 050460f6 authored by Phillip Webb's avatar Phillip Webb

Check factory bean for EntityManager datasource

Update `DataSourceInitializedPublisher` to fallback to the
`LocalContainerEntityManagerFactoryBean` if the
`javax.persistence.nonJtaDataSource` property is not defined.

As of Hibernate 4.3 the property is no longer set if the `EntityManager`
is created from a `PersistenceUnitInfo` instance rather than actual
properties.

Although this is being addressed in Hibernate issue HHH-13432, it's
not strictly a requirement of the JPA spec that the property is set.

Fixes gh-17061
parent 9c09c7d5
...@@ -65,8 +65,7 @@ class DataSourceInitializedPublisher implements BeanPostProcessor { ...@@ -65,8 +65,7 @@ class DataSourceInitializedPublisher implements BeanPostProcessor {
if (bean instanceof LocalContainerEntityManagerFactoryBean) { if (bean instanceof LocalContainerEntityManagerFactoryBean) {
LocalContainerEntityManagerFactoryBean factory = (LocalContainerEntityManagerFactoryBean) bean; LocalContainerEntityManagerFactoryBean factory = (LocalContainerEntityManagerFactoryBean) bean;
if (factory.getBootstrapExecutor() != null && factory.getJpaVendorAdapter() != null) { if (factory.getBootstrapExecutor() != null && factory.getJpaVendorAdapter() != null) {
this.schemaCreatedPublisher = new DataSourceSchemaCreatedPublisher(factory.getBootstrapExecutor(), this.schemaCreatedPublisher = new DataSourceSchemaCreatedPublisher(factory);
factory.getJpaVendorAdapter());
factory.setJpaVendorAdapter(this.schemaCreatedPublisher); factory.setJpaVendorAdapter(this.schemaCreatedPublisher);
} }
} }
...@@ -86,21 +85,27 @@ class DataSourceInitializedPublisher implements BeanPostProcessor { ...@@ -86,21 +85,27 @@ class DataSourceInitializedPublisher implements BeanPostProcessor {
this.hibernateProperties = (HibernateProperties) bean; this.hibernateProperties = (HibernateProperties) bean;
} }
if (bean instanceof LocalContainerEntityManagerFactoryBean && this.schemaCreatedPublisher == null) { if (bean instanceof LocalContainerEntityManagerFactoryBean && this.schemaCreatedPublisher == null) {
LocalContainerEntityManagerFactoryBean factory = (LocalContainerEntityManagerFactoryBean) bean; LocalContainerEntityManagerFactoryBean factoryBean = (LocalContainerEntityManagerFactoryBean) bean;
publishEventIfRequired(factory.getNativeEntityManagerFactory()); EntityManagerFactory entityManagerFactory = factoryBean.getNativeEntityManagerFactory();
publishEventIfRequired(factoryBean, entityManagerFactory);
} }
return bean; return bean;
} }
private void publishEventIfRequired(EntityManagerFactory entityManagerFactory) { private void publishEventIfRequired(LocalContainerEntityManagerFactoryBean factoryBean,
DataSource dataSource = findDataSource(entityManagerFactory); EntityManagerFactory entityManagerFactory) {
DataSource dataSource = findDataSource(factoryBean, entityManagerFactory);
if (dataSource != null && isInitializingDatabase(dataSource)) { if (dataSource != null && isInitializingDatabase(dataSource)) {
this.applicationContext.publishEvent(new DataSourceSchemaCreatedEvent(dataSource)); this.applicationContext.publishEvent(new DataSourceSchemaCreatedEvent(dataSource));
} }
} }
private DataSource findDataSource(EntityManagerFactory entityManagerFactory) { private DataSource findDataSource(LocalContainerEntityManagerFactoryBean factoryBean,
EntityManagerFactory entityManagerFactory) {
Object dataSource = entityManagerFactory.getProperties().get("javax.persistence.nonJtaDataSource"); Object dataSource = entityManagerFactory.getProperties().get("javax.persistence.nonJtaDataSource");
if (dataSource == null) {
dataSource = factoryBean.getPersistenceUnitInfo().getNonJtaDataSource();
}
return (dataSource instanceof DataSource) ? (DataSource) dataSource : this.dataSource; return (dataSource instanceof DataSource) ? (DataSource) dataSource : this.dataSource;
} }
...@@ -145,14 +150,13 @@ class DataSourceInitializedPublisher implements BeanPostProcessor { ...@@ -145,14 +150,13 @@ class DataSourceInitializedPublisher implements BeanPostProcessor {
final class DataSourceSchemaCreatedPublisher implements JpaVendorAdapter { final class DataSourceSchemaCreatedPublisher implements JpaVendorAdapter {
private final AsyncTaskExecutor bootstrapExecutor; private final LocalContainerEntityManagerFactoryBean factoryBean;
private final JpaVendorAdapter delegate; private final JpaVendorAdapter delegate;
private DataSourceSchemaCreatedPublisher(AsyncTaskExecutor bootstrapExecutor, private DataSourceSchemaCreatedPublisher(LocalContainerEntityManagerFactoryBean factoryBean) {
JpaVendorAdapter jpaVendorAdapter) { this.factoryBean = factoryBean;
this.bootstrapExecutor = bootstrapExecutor; this.delegate = factoryBean.getJpaVendorAdapter();
this.delegate = jpaVendorAdapter;
} }
@Override @Override
...@@ -191,10 +195,12 @@ class DataSourceInitializedPublisher implements BeanPostProcessor { ...@@ -191,10 +195,12 @@ class DataSourceInitializedPublisher implements BeanPostProcessor {
} }
@Override @Override
public void postProcessEntityManagerFactory(EntityManagerFactory emf) { public void postProcessEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
this.delegate.postProcessEntityManagerFactory(emf); this.delegate.postProcessEntityManagerFactory(entityManagerFactory);
if (this.bootstrapExecutor != null) { AsyncTaskExecutor bootstrapExecutor = this.factoryBean.getBootstrapExecutor();
this.bootstrapExecutor.execute(() -> DataSourceInitializedPublisher.this.publishEventIfRequired(emf)); if (bootstrapExecutor != null) {
bootstrapExecutor.execute(() -> DataSourceInitializedPublisher.this
.publishEventIfRequired(this.factoryBean, entityManagerFactory));
} }
} }
......
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