From 00474ceecdd78fedfae3cafe32a5da2e4853074b Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 1 Nov 2013 23:50:09 +0100 Subject: [PATCH] Introduced setCacheRegionFactory method on LocalSessionFactoryBuilder/Bean Issue: SPR-11056 --- .../hibernate4/LocalSessionFactoryBean.java | 19 ++++++++++ .../LocalSessionFactoryBuilder.java | 37 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java index 9eec19172f3..267e3288053 100644 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java +++ b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java @@ -23,6 +23,7 @@ import javax.sql.DataSource; import org.hibernate.Interceptor; import org.hibernate.SessionFactory; +import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.NamingStrategy; @@ -88,6 +89,8 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator private Object currentTenantIdentifierResolver; + private RegionFactory cacheRegionFactory; + private Properties hibernateProperties; private Class[] annotatedClasses; @@ -246,6 +249,18 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator this.currentTenantIdentifierResolver = currentTenantIdentifierResolver; } + /** + * Set the Hibernate RegionFactory to use for the SessionFactory. + * Allows for using a Spring-managed RegionFactory instance. + *

Note: If this is set, the Hibernate settings should not define a + * cache provider to avoid meaningless double configuration. + * @see org.hibernate.cache.spi.RegionFactory + * @see LocalSessionFactoryBuilder#setCacheRegionFactory + */ + public void setCacheRegionFactory(RegionFactory cacheRegionFactory) { + this.cacheRegionFactory = cacheRegionFactory; + } + /** * Set Hibernate properties, such as "hibernate.dialect". *

Note: Do not specify a transaction provider here when using @@ -372,6 +387,10 @@ public class LocalSessionFactoryBean extends HibernateExceptionTranslator sfb.setCurrentTenantIdentifierResolver(this.currentTenantIdentifierResolver); } + if (this.cacheRegionFactory != null) { + sfb.setCacheRegionFactory(this.cacheRegionFactory); + } + if (this.hibernateProperties != null) { sfb.addProperties(this.hibernateProperties); } diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java index c22bf01670f..36bfcd76d3f 100644 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java +++ b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java @@ -18,7 +18,9 @@ package org.springframework.orm.hibernate4; import java.io.IOException; import java.lang.annotation.Annotation; +import java.lang.reflect.Method; import java.util.LinkedHashSet; +import java.util.Properties; import java.util.Set; import javax.persistence.Embeddable; import javax.persistence.Entity; @@ -29,10 +31,13 @@ import javax.transaction.TransactionManager; import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.SessionFactory; +import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; +import org.hibernate.cfg.Settings; import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory; +import org.hibernate.service.ServiceRegistry; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; @@ -97,6 +102,8 @@ public class LocalSessionFactoryBuilder extends Configuration { private final ResourcePatternResolver resourcePatternResolver; + private RegionFactory cacheRegionFactory; + /** * Create a new LocalSessionFactoryBuilder for the given DataSource. @@ -199,6 +206,18 @@ public class LocalSessionFactoryBuilder extends Configuration { return this; } + /** + * Set the Hibernate RegionFactory to use for the SessionFactory. + * Allows for using a Spring-managed RegionFactory instance. + *

Note: If this is set, the Hibernate settings should not define a + * cache provider to avoid meaningless double configuration. + * @see org.hibernate.cache.spi.RegionFactory + */ + public LocalSessionFactoryBuilder setCacheRegionFactory(RegionFactory cacheRegionFactory) { + this.cacheRegionFactory = cacheRegionFactory; + return this; + } + /** * Add the given annotated classes in a batch. * @see #addAnnotatedClass @@ -273,6 +292,24 @@ public class LocalSessionFactoryBuilder extends Configuration { } + // Overridden methods from Hibernate's Configuration class + + @Override + public Settings buildSettings(Properties props, ServiceRegistry serviceRegistry) throws HibernateException { + Settings settings = super.buildSettings(props, serviceRegistry); + if (this.cacheRegionFactory != null) { + try { + Method setRegionFactory = Settings.class.getDeclaredMethod("setRegionFactory", RegionFactory.class); + setRegionFactory.setAccessible(true); + setRegionFactory.invoke(settings, this.cacheRegionFactory); + } + catch (Exception ex) { + throw new IllegalStateException("Failed to invoke Hibernate's setRegionFactory method", ex); + } + } + return settings; + } + /** * Build the {@code SessionFactory}. */