From b6d95567e84bbf5f3f25f5c403ac0ed57b376076 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 28 Jun 2018 13:43:43 +0200 Subject: [PATCH] Explicit support for Hibernate Integrators on LocalSessionFactoryBean Issue: SPR-16828 --- .../hibernate5/LocalSessionFactoryBean.java | 36 +++++++++++++++---- .../LocalSessionFactoryBuilder.java | 6 ++-- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java index 9a84c03483c..f0cdd0a29cf 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBean.java @@ -30,6 +30,8 @@ import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.context.spi.CurrentTenantIdentifierResolver; import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider; +import org.hibernate.integrator.spi.Integrator; +import org.hibernate.service.ServiceRegistry; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; @@ -44,15 +46,13 @@ import org.springframework.core.io.support.ResourcePatternUtils; import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.type.filter.TypeFilter; import org.springframework.lang.Nullable; -import org.springframework.util.Assert; /** - * {@link FactoryBean} that creates a Hibernate - * {@link SessionFactory}. This is the usual way to set up a shared - * Hibernate SessionFactory in a Spring application context; the SessionFactory can - * then be passed to Hibernate-based data access objects via dependency injection. + * {@link FactoryBean} that creates a Hibernate {@link SessionFactory}. This is the usual + * way to set up a shared Hibernate SessionFactory in a Spring application context; the + * SessionFactory can then be passed to data access objects via dependency injection. * - *

Compatible with Hibernate 5.0/5.1 as well as 5.2, as of Spring 4.3. + *

Compatible with Hibernate 5.0/5.1 as well as 5.2/5.3, as of Spring 5.1. * * @author Juergen Hoeller * @since 4.2 @@ -120,6 +120,9 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator @Nullable private AsyncTaskExecutor bootstrapExecutor; + @Nullable + private Integrator[] hibernateIntegrators; + private boolean metadataSourcesAccessed = false; @Nullable @@ -358,14 +361,28 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator this.bootstrapExecutor = bootstrapExecutor; } + /** + * Specify one or more Hibernate {@link Integrator} implementations to apply. + *

This will only be applied for an internally built {@link MetadataSources} + * instance. {@link #setMetadataSources} effectively overrides such settings, + * with integrators to be applied to the externally built {@link MetadataSources}. + * @since 5.1 + * @see #setMetadataSources + * @see BootstrapServiceRegistryBuilder#applyIntegrator + */ + public void setHibernateIntegrators(Integrator... hibernateIntegrators) { + this.hibernateIntegrators = hibernateIntegrators; + } + /** * Specify a Hibernate {@link MetadataSources} service to use (e.g. reusing an * existing one), potentially populated with a custom Hibernate bootstrap * {@link org.hibernate.service.ServiceRegistry} as well. * @since 4.3 + * @see MetadataSources#MetadataSources(ServiceRegistry) + * @see BootstrapServiceRegistryBuilder#build() */ public void setMetadataSources(MetadataSources metadataSources) { - Assert.notNull(metadataSources, "MetadataSources must not be null"); this.metadataSourcesAccessed = true; this.metadataSources = metadataSources; } @@ -385,6 +402,11 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator if (this.resourcePatternResolver != null) { builder = builder.applyClassLoader(this.resourcePatternResolver.getClassLoader()); } + if (this.hibernateIntegrators != null) { + for (Integrator integrator : this.hibernateIntegrators) { + builder = builder.applyIntegrator(integrator); + } + } this.metadataSources = new MetadataSources(builder.build()); } return this.metadataSources; diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java index 16358154c24..7ea1c4573e6 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/LocalSessionFactoryBuilder.java @@ -71,7 +71,7 @@ import org.springframework.util.ClassUtils; *

This is designed for programmatic use, e.g. in {@code @Bean} factory methods. * Consider using {@link LocalSessionFactoryBean} for XML bean definition files. * - *

Compatible with Hibernate 5.0/5.1 as well as 5.2, as of Spring 4.3. + *

Compatible with Hibernate 5.0/5.1 as well as 5.2/5.3, as of Spring 5.1. * * @author Juergen Hoeller * @since 4.2 @@ -136,7 +136,9 @@ public class LocalSessionFactoryBuilder extends Configuration { * @param metadataSources the Hibernate MetadataSources service to use (e.g. reusing an existing one) * @since 4.3 */ - public LocalSessionFactoryBuilder(@Nullable DataSource dataSource, ResourceLoader resourceLoader, MetadataSources metadataSources) { + public LocalSessionFactoryBuilder( + @Nullable DataSource dataSource, ResourceLoader resourceLoader, MetadataSources metadataSources) { + super(metadataSources); getProperties().put(AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName());