Browse Source

SpringBeanContainer is public for custom JPA configuration purposes

Issue: SPR-16305
pull/1870/head
Juergen Hoeller 7 years ago
parent
commit
620e83c35d
  1. 10
      spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java
  2. 21
      spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java
  3. 42
      spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringBeanContainer.java

10
spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java

@ -57,12 +57,21 @@ import org.springframework.util.ClassUtils; @@ -57,12 +57,21 @@ import org.springframework.util.ClassUtils;
* SessionFactory can then be passed to data access objects via dependency injection.
*
* <p>Compatible with Hibernate 5.0/5.1 as well as 5.2/5.3, as of Spring 5.1.
* Set up with Hibernate 5.3, {@code LocalSessionFactoryBean} is an immediate alternative
* to {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean} for common
* JPA purposes: In particular with Hibernate 5.3, the Hibernate {@code SessionFactory}
* will natively expose the JPA {@code EntityManagerFactory} interface as well, and
* Hibernate {@code BeanContainer} integration will be registered out of the box.
* In combination with {@link HibernateTransactionManager}, this naturally allows for
* mixing JPA access code with native Hibernate access code within the same transaction.
*
* @author Juergen Hoeller
* @since 4.2
* @see #setDataSource
* @see #setPackagesToScan
* @see HibernateTransactionManager
* @see LocalSessionFactoryBuilder
* @see org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
*/
public class LocalSessionFactoryBean extends HibernateExceptionTranslator
implements FactoryBean<SessionFactory>, ResourceLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean {
@ -446,6 +455,7 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator @@ -446,6 +455,7 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator
* it if possible. This requires a Spring {@link ConfigurableListableBeanFactory}
* and Hibernate 5.3 or higher on the classpath.
* @since 5.1
* @see SpringBeanContainer
* @see LocalSessionFactoryBuilder#setBeanContainer
*/
@Override

21
spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java

@ -67,16 +67,30 @@ import org.springframework.util.ClassUtils; @@ -67,16 +67,30 @@ import org.springframework.util.ClassUtils;
/**
* A Spring-provided extension of the standard Hibernate {@link Configuration} class,
* adding {@link SpringSessionContext} as a default and providing convenient ways
* to specify a DataSource and an application class loader.
* to specify a JDBC {@link DataSource} and an application class loader.
*
* <p>This is designed for programmatic use, e.g. in {@code @Bean} factory methods.
* Consider using {@link LocalSessionFactoryBean} for XML bean definition files.
* <p>This is designed for programmatic use, e.g. in {@code @Bean} factory methods;
* consider using {@link LocalSessionFactoryBean} for XML bean definition files.
* Typically combined with {@link HibernateTransactionManager} for declarative
* transactions against the {@code SessionFactory} and its JDBC {@code DataSource}.
*
* <p>Compatible with Hibernate 5.0/5.1 as well as 5.2/5.3, as of Spring 5.1.
* Set up with Hibernate 5.2/5.3, this builder is also a convenient way to set up
* a JPA {@code EntityManagerFactory} since the Hibernate {@code SessionFactory}
* natively exposes the JPA {@code EntityManagerFactory} interface as well now.
*
* <p>This builder supports Hibernate 5.3 {@code BeanContainer} integration,
* {@link MetadataSources} from custom {@link BootstrapServiceRegistryBuilder}
* setup, as well as other advanced Hibernate configuration options beyond the
* standard JPA bootstrap contract.
*
* @author Juergen Hoeller
* @since 4.2
* @see HibernateTransactionManager
* @see LocalSessionFactoryBean
* @see #setBeanContainer
* @see #LocalSessionFactoryBuilder(DataSource, ResourceLoader, MetadataSources)
* @see BootstrapServiceRegistryBuilder
*/
@SuppressWarnings("serial")
public class LocalSessionFactoryBuilder extends Configuration {
@ -235,6 +249,7 @@ public class LocalSessionFactoryBuilder extends Configuration { @@ -235,6 +249,7 @@ public class LocalSessionFactoryBuilder extends Configuration {
* <p>Note: Bean container integration requires Hibernate 5.3 or higher.
* It enables autowiring of Hibernate attribute converters and entity listeners.
* @since 5.1
* @see SpringBeanContainer
* @see AvailableSettings#BEAN_CONTAINER
*/
public LocalSessionFactoryBuilder setBeanContainer(ConfigurableListableBeanFactory beanFactory) {

42
spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringBeanContainer.java

@ -26,23 +26,63 @@ import org.hibernate.resource.beans.spi.BeanInstanceProducer; @@ -26,23 +26,63 @@ import org.hibernate.resource.beans.spi.BeanInstanceProducer;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ConcurrentReferenceHashMap;
/**
* Spring's implementation of Hibernate 5.3's {@link BeanContainer} SPI,
* delegating to a Spring {@link ConfigurableListableBeanFactory}.
*
* <p>Auto-configured by {@link LocalSessionFactoryBean#setBeanFactory},
* programmatically supported via {@link LocalSessionFactoryBuilder#setBeanContainer},
* and manually configurable through a "hibernate.resource.beans.container" entry
* in JPA properties, e.g.:
*
* <pre class="code">
* &lt;bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;
* ...
* &lt;property name="jpaPropertyMap"&gt;
* &lt;map>
* &lt;entry key="hibernate.resource.beans.container"&gt;
* &lt;bean class="org.springframework.orm.hibernate5.SpringBeanContainer"/&gt;
* &lt;/entry&gt;
* &lt;/map&gt;
* &lt;/property&gt;
* &lt;/bean&gt;</pre>
*
* Or in Java-based JPA configuration:
*
* <pre class="code">
* LocalContainerEntityManagerFactoryBean emfb = ...
* emfb.getJpaPropertyMap().put(AvailableSettings.BEAN_CONTAINER, new SpringBeanContainer(beanFactory));
* </pre>
*
* Please note that Spring's {@link LocalSessionFactoryBean} is an immediate alternative
* to {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean} for common
* JPA purposes: In particular with Hibernate 5.3, the Hibernate {@code SessionFactory}
* will natively expose the JPA {@code EntityManagerFactory} interface as well, and
* Hibernate {@code BeanContainer} integration will be registered out of the box.
*
* @author Juergen Hoeller
* @since 5.1
* @see LocalSessionFactoryBean#setBeanFactory
* @see LocalSessionFactoryBuilder#setBeanContainer
* @see org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#setJpaPropertyMap
* @see org.hibernate.cfg.AvailableSettings#BEAN_CONTAINER
*/
final class SpringBeanContainer implements BeanContainer {
public final class SpringBeanContainer implements BeanContainer {
private final ConfigurableListableBeanFactory beanFactory;
private final Map<Object, SpringContainedBean<?>> beanCache = new ConcurrentReferenceHashMap<>();
/**
* Instantiate a new SpringBeanContainer for the given bean factory.
* @param beanFactory the Spring bean factory to delegate to
*/
public SpringBeanContainer(ConfigurableListableBeanFactory beanFactory) {
Assert.notNull(beanFactory, "ConfigurableListableBeanFactory is required");
this.beanFactory = beanFactory;
}

Loading…
Cancel
Save