Register SpringBeanContainer with default Hibernate setup
Closes gh-13717
This commit is contained in:
parent
7bf32290c6
commit
068040e227
|
@ -16,10 +16,10 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.orm.jpa;
|
package org.springframework.boot.autoconfigure.orm.jpa;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
@ -31,8 +31,10 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
|
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
|
||||||
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
|
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
|
||||||
import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers;
|
import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
@ -43,6 +45,7 @@ import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider;
|
||||||
import org.springframework.boot.orm.jpa.hibernate.SpringJtaPlatform;
|
import org.springframework.boot.orm.jpa.hibernate.SpringJtaPlatform;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.jndi.JndiLocatorDelegate;
|
import org.springframework.jndi.JndiLocatorDelegate;
|
||||||
|
import org.springframework.orm.hibernate5.SpringBeanContainer;
|
||||||
import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
|
import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
|
||||||
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||||
|
@ -85,6 +88,7 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration {
|
||||||
private final List<HibernatePropertiesCustomizer> hibernatePropertiesCustomizers;
|
private final List<HibernatePropertiesCustomizer> hibernatePropertiesCustomizers;
|
||||||
|
|
||||||
HibernateJpaConfiguration(DataSource dataSource, JpaProperties jpaProperties,
|
HibernateJpaConfiguration(DataSource dataSource, JpaProperties jpaProperties,
|
||||||
|
ConfigurableListableBeanFactory beanFactory,
|
||||||
ObjectProvider<JtaTransactionManager> jtaTransactionManager,
|
ObjectProvider<JtaTransactionManager> jtaTransactionManager,
|
||||||
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers,
|
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers,
|
||||||
HibernateProperties hibernateProperties,
|
HibernateProperties hibernateProperties,
|
||||||
|
@ -101,22 +105,25 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration {
|
||||||
metadataProviders.getIfAvailable());
|
metadataProviders.getIfAvailable());
|
||||||
this.hibernatePropertiesCustomizers = determineHibernatePropertiesCustomizers(
|
this.hibernatePropertiesCustomizers = determineHibernatePropertiesCustomizers(
|
||||||
physicalNamingStrategy.getIfAvailable(),
|
physicalNamingStrategy.getIfAvailable(),
|
||||||
implicitNamingStrategy.getIfAvailable(), hibernatePropertiesCustomizers
|
implicitNamingStrategy.getIfAvailable(), beanFactory,
|
||||||
.orderedStream().collect(Collectors.toList()));
|
hibernatePropertiesCustomizers.orderedStream()
|
||||||
|
.collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<HibernatePropertiesCustomizer> determineHibernatePropertiesCustomizers(
|
private List<HibernatePropertiesCustomizer> determineHibernatePropertiesCustomizers(
|
||||||
PhysicalNamingStrategy physicalNamingStrategy,
|
PhysicalNamingStrategy physicalNamingStrategy,
|
||||||
ImplicitNamingStrategy implicitNamingStrategy,
|
ImplicitNamingStrategy implicitNamingStrategy,
|
||||||
|
ConfigurableListableBeanFactory beanFactory,
|
||||||
List<HibernatePropertiesCustomizer> hibernatePropertiesCustomizers) {
|
List<HibernatePropertiesCustomizer> hibernatePropertiesCustomizers) {
|
||||||
|
List<HibernatePropertiesCustomizer> customizers = new ArrayList<>();
|
||||||
|
customizers.add((properties) -> properties.put(AvailableSettings.BEAN_CONTAINER,
|
||||||
|
new SpringBeanContainer(beanFactory)));
|
||||||
if (physicalNamingStrategy != null || implicitNamingStrategy != null) {
|
if (physicalNamingStrategy != null || implicitNamingStrategy != null) {
|
||||||
LinkedList<HibernatePropertiesCustomizer> customizers = new LinkedList<>(
|
customizers.add(new NamingStrategiesHibernatePropertiesCustomizer(
|
||||||
hibernatePropertiesCustomizers);
|
|
||||||
customizers.addFirst(new NamingStrategiesHibernatePropertiesCustomizer(
|
|
||||||
physicalNamingStrategy, implicitNamingStrategy));
|
physicalNamingStrategy, implicitNamingStrategy));
|
||||||
return customizers;
|
|
||||||
}
|
}
|
||||||
return hibernatePropertiesCustomizers;
|
customizers.addAll(hibernatePropertiesCustomizers);
|
||||||
|
return customizers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -35,6 +35,7 @@ import javax.transaction.UserTransaction;
|
||||||
import com.zaxxer.hikari.HikariDataSource;
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
|
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
|
||||||
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
|
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
|
||||||
|
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;
|
||||||
|
@ -361,6 +362,27 @@ public class HibernateJpaAutoConfigurationTests
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void eventListenerCanBeRegisteredAsBeans() {
|
||||||
|
contextRunner().withUserConfiguration(TestInitializedJpaConfiguration.class)
|
||||||
|
.withClassLoader(new HideDataScriptClassLoader())
|
||||||
|
.withPropertyValues("spring.jpa.show-sql=true",
|
||||||
|
"spring.jpa.hibernate.ddl-auto:create-drop",
|
||||||
|
"spring.datasource.data:classpath:/city.sql")
|
||||||
|
.run((context) -> {
|
||||||
|
// See CityListener
|
||||||
|
assertThat(context).hasSingleBean(City.class);
|
||||||
|
assertThat(context.getBean(City.class).getName())
|
||||||
|
.isEqualTo("Washington");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hibernatePropertiesCustomizerCanDisableBeanContainer() {
|
||||||
|
contextRunner().withUserConfiguration(DisableBeanContainerConfiguration.class)
|
||||||
|
.run((context) -> assertThat(context).doesNotHaveBean(City.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@TestAutoConfigurationPackage(City.class)
|
@TestAutoConfigurationPackage(City.class)
|
||||||
static class TestInitializedJpaConfiguration {
|
static class TestInitializedJpaConfiguration {
|
||||||
|
@ -420,6 +442,17 @@ public class HibernateJpaAutoConfigurationTests
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class DisableBeanContainerConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public HibernatePropertiesCustomizer disableBeanContainerHibernatePropertiesCustomizer() {
|
||||||
|
return (hibernateProperties) -> hibernateProperties
|
||||||
|
.remove(AvailableSettings.BEAN_CONTAINER);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static class TestJtaPlatform implements JtaPlatform {
|
public static class TestJtaPlatform implements JtaPlatform {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -20,10 +20,12 @@ import java.io.Serializable;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EntityListeners;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
|
@EntityListeners(CityListener.class)
|
||||||
public class City implements Serializable {
|
public class City implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2018 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.autoconfigure.orm.jpa.test;
|
||||||
|
|
||||||
|
import javax.persistence.PostLoad;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
|
||||||
|
public class CityListener {
|
||||||
|
|
||||||
|
private ConfigurableBeanFactory beanFactory;
|
||||||
|
|
||||||
|
public CityListener() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public CityListener(ConfigurableBeanFactory beanFactory) {
|
||||||
|
this.beanFactory = beanFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostLoad
|
||||||
|
public void postLoad(City city) {
|
||||||
|
if (this.beanFactory != null) {
|
||||||
|
this.beanFactory.registerSingleton(City.class.getName(), city);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2000,6 +2000,17 @@ for more details.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[[howto-use-dependency-injection-hibernate-components]]
|
||||||
|
=== Use Dependency Injection in Hibernate Components
|
||||||
|
By default, Spring Boot registers a `BeanContainer` implementation that uses the
|
||||||
|
`BeanFactory` so that converters and entity listeners can use regular dependency
|
||||||
|
injection.
|
||||||
|
|
||||||
|
You can disable or tune this behaviour by registering a `HibernatePropertiesCustomizer`
|
||||||
|
that remove or change the `hibernate.resource.beans.container` property.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[howto-use-custom-entity-manager]]
|
[[howto-use-custom-entity-manager]]
|
||||||
=== Use a Custom EntityManagerFactory
|
=== Use a Custom EntityManagerFactory
|
||||||
To take full control of the configuration of the `EntityManagerFactory`, you need to add
|
To take full control of the configuration of the `EntityManagerFactory`, you need to add
|
||||||
|
|
|
@ -66,7 +66,7 @@ Phillip Webb; Dave Syer; Josh Long; Stéphane Nicoll; Rob Winch; Andy Wilkinson;
|
||||||
:code-examples: ../java/org/springframework/boot/docs
|
:code-examples: ../java/org/springframework/boot/docs
|
||||||
:test-examples: ../../test/java/org/springframework/boot/docs
|
:test-examples: ../../test/java/org/springframework/boot/docs
|
||||||
:gradle-user-guide: https://docs.gradle.org/4.2.1/userguide
|
:gradle-user-guide: https://docs.gradle.org/4.2.1/userguide
|
||||||
:hibernate-documentation: https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html
|
:hibernate-documentation: https://docs.jboss.org/hibernate/orm/5.3/userguide/html_single/Hibernate_User_Guide.html
|
||||||
:jetty-documentation: https://www.eclipse.org/jetty/documentation/9.4.x
|
:jetty-documentation: https://www.eclipse.org/jetty/documentation/9.4.x
|
||||||
:jooq-manual: https://www.jooq.org/doc/{jooq-version}/manual-single-page
|
:jooq-manual: https://www.jooq.org/doc/{jooq-version}/manual-single-page
|
||||||
:micrometer-concepts-documentation: https://micrometer.io/docs/concepts
|
:micrometer-concepts-documentation: https://micrometer.io/docs/concepts
|
||||||
|
|
Loading…
Reference in New Issue