diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalCacheProviderProxy.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalCacheProviderProxy.java index a61273740a0..e240800e0f3 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalCacheProviderProxy.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalCacheProviderProxy.java @@ -29,7 +29,7 @@ import org.hibernate.cache.CacheProvider; * * @author Juergen Hoeller * @since 2.5.1 - * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#setCacheProvider + * @see LocalSessionFactoryBean#setCacheProvider */ public class LocalCacheProviderProxy implements CacheProvider { diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalRegionFactoryProxy.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalRegionFactoryProxy.java new file mode 100644 index 00000000000..1f52c6b7fdb --- /dev/null +++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalRegionFactoryProxy.java @@ -0,0 +1,95 @@ +/* + * Copyright 2002-2009 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.orm.hibernate3; + +import java.util.Properties; + +import org.hibernate.cache.CacheDataDescription; +import org.hibernate.cache.CacheException; +import org.hibernate.cache.CollectionRegion; +import org.hibernate.cache.EntityRegion; +import org.hibernate.cache.QueryResultsRegion; +import org.hibernate.cache.RegionFactory; +import org.hibernate.cache.TimestampsRegion; +import org.hibernate.cfg.Settings; + +/** + * Proxy for a Hibernate RegionFactory, delegating to a Spring-managed + * RegionFactory instance, determined by LocalSessionFactoryBean's + * "cacheRegionFactory" property. + * + * @author Juergen Hoeller + * @since 3.0 + * @see LocalSessionFactoryBean#setCacheRegionFactory + */ +public class LocalRegionFactoryProxy implements RegionFactory { + + private final RegionFactory regionFactory; + + + public LocalRegionFactoryProxy() { + RegionFactory rf = LocalSessionFactoryBean.getConfigTimeRegionFactory(); + // absolutely needs thread-bound RegionFactory to initialize + if (rf == null) { + throw new IllegalStateException("No Hibernate RegionFactory found - " + + "'cacheRegionFactory' property must be set on LocalSessionFactoryBean"); + } + this.regionFactory = rf; + } + + + public void start(Settings settings, Properties properties) throws CacheException { + this.regionFactory.start(settings, properties); + } + + public void stop() { + this.regionFactory.stop(); + } + + public boolean isMinimalPutsEnabledByDefault() { + return this.regionFactory.isMinimalPutsEnabledByDefault(); + } + + public long nextTimestamp() { + return this.regionFactory.nextTimestamp(); + } + + public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) + throws CacheException { + + return this.regionFactory.buildEntityRegion(regionName, properties, metadata); + } + + public CollectionRegion buildCollectionRegion(String regionName, Properties properties, + CacheDataDescription metadata) throws CacheException { + + return this.regionFactory.buildCollectionRegion(regionName, properties, metadata); + } + + public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) + throws CacheException { + + return this.regionFactory.buildQueryResultsRegion(regionName, properties); + } + + public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) + throws CacheException { + + return this.regionFactory.buildTimestampsRegion(regionName, properties); + } + +} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalSessionFactoryBean.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalSessionFactoryBean.java index ac77e4a9ab3..19fb9a08b40 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalSessionFactoryBean.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalSessionFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 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. @@ -34,12 +34,14 @@ import org.hibernate.Interceptor; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cache.CacheProvider; +import org.hibernate.cache.RegionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.cfg.NamingStrategy; import org.hibernate.dialect.Dialect; import org.hibernate.engine.FilterDefinition; import org.hibernate.event.EventListeners; +import org.hibernate.jdbc.Work; import org.hibernate.tool.hbm2ddl.DatabaseMetadata; import org.hibernate.transaction.JTATransactionFactory; @@ -88,7 +90,7 @@ import org.springframework.util.StringUtils; * {@link org.springframework.orm.hibernate3.support.OpenSessionInViewFilter} / * {@link org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor}. * - *
Requires Hibernate 3.2 or later. Note that this factory will use + *
Requires Hibernate 3.3 or later. Note that this factory will use
* "on_close" as default Hibernate connection release mode, unless in the
* case of a "jtaTransactionManager" specified, for the reason that
* this is appropriate for most Spring-based applications (in particular when
@@ -113,6 +115,9 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen
private static final ThreadLocal This instance will be set before initialization of the corresponding
+ * SessionFactory, and reset immediately afterwards. It is thus only available
+ * during configuration.
+ * @see #setCacheRegionFactory
+ */
+ public static RegionFactory getConfigTimeRegionFactory() {
+ return configTimeRegionFactoryHolder.get();
+ }
+
/**
* Return the CacheProvider for the currently configured Hibernate SessionFactory,
* to be used by LocalCacheProviderProxy.
@@ -173,7 +190,7 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen
}
- private Class configurationClass = Configuration.class;
+ private Class extends Configuration> configurationClass = Configuration.class;
private Resource[] configLocations;
@@ -191,6 +208,8 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen
private TransactionManager jtaTransactionManager;
+ private RegionFactory cacheRegionFactory;
+
private CacheProvider cacheProvider;
private LobHandler lobHandler;
@@ -231,12 +250,13 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen
* @see org.hibernate.cfg.Configuration
* @see org.hibernate.cfg.AnnotationConfiguration
*/
- public void setConfigurationClass(Class configurationClass) {
+ @SuppressWarnings("unchecked")
+ public void setConfigurationClass(Class> configurationClass) {
if (configurationClass == null || !Configuration.class.isAssignableFrom(configurationClass)) {
throw new IllegalArgumentException(
- "configurationClass must be assignable to [org.hibernate.cfg.Configuration]");
+ "'configurationClass' must be assignable to [org.hibernate.cfg.Configuration]");
}
- this.configurationClass = configurationClass;
+ this.configurationClass = (Class extends Configuration>) configurationClass;
}
/**
@@ -359,13 +379,29 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen
this.jtaTransactionManager = jtaTransactionManager;
}
+ /**
+ * Set the Hibernate RegionFactory to use for the SessionFactory.
+ * Allows for using a Spring-managed RegionFactory instance.
+ * As of Hibernate 3.3, this is the preferred mechanism for configuring
+ * caches, superseding the {@link #setCacheProvider CacheProvider SPI}.
+ * Note: If this is set, the Hibernate settings should not define a
+ * cache provider to avoid meaningless double configuration.
+ * @see LocalRegionFactoryProxy
+ */
+ public void setCacheRegionFactory(RegionFactory cacheRegionFactory) {
+ this.cacheRegionFactory = cacheRegionFactory;
+ }
+
/**
* Set the Hibernate CacheProvider to use for the SessionFactory.
* Allows for using a Spring-managed CacheProvider instance.
* Note: If this is set, the Hibernate settings should not define a
* cache provider to avoid meaningless double configuration.
- * @see LocalCacheProviderProxy
+ * @deprecated as of Spring 3.0, following Hibernate 3.3's deprecation
+ * of the CacheProvider SPI
+ * @see #setCacheRegionFactory
*/
+ @Deprecated
public void setCacheProvider(CacheProvider cacheProvider) {
this.cacheProvider = cacheProvider;
}
@@ -523,6 +559,10 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen
// Make Spring-provided JTA TransactionManager available.
configTimeTransactionManagerHolder.set(this.jtaTransactionManager);
}
+ if (this.cacheRegionFactory != null) {
+ // Make Spring-provided Hibernate RegionFactory available.
+ configTimeRegionFactoryHolder.set(this.cacheRegionFactory);
+ }
if (this.cacheProvider != null) {
// Make Spring-provided Hibernate CacheProvider available.
configTimeCacheProviderHolder.set(this.cacheProvider);
@@ -622,7 +662,11 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen
config.setProperty(Environment.CONNECTION_PROVIDER, providerClass.getName());
}
- if (this.cacheProvider != null) {
+ if (this.cacheRegionFactory != null) {
+ // Expose Spring-provided Hibernate RegionFactory.
+ config.setProperty(Environment.CACHE_REGION_FACTORY, LocalRegionFactoryProxy.class.getName());
+ }
+ else if (this.cacheProvider != null) {
// Expose Spring-provided Hibernate CacheProvider.
config.setProperty(Environment.CACHE_PROVIDER, LocalCacheProviderProxy.class.getName());
}
@@ -733,19 +777,18 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen
finally {
if (dataSource != null) {
- // Reset DataSource holder.
configTimeDataSourceHolder.set(null);
}
if (this.jtaTransactionManager != null) {
- // Reset TransactionManager holder.
configTimeTransactionManagerHolder.set(null);
}
+ if (this.cacheRegionFactory != null) {
+ configTimeCacheProviderHolder.set(null);
+ }
if (this.cacheProvider != null) {
- // Reset CacheProvider holder.
configTimeCacheProviderHolder.set(null);
}
if (this.lobHandler != null) {
- // Reset LobHandler holder.
configTimeLobHandlerHolder.set(null);
}
if (overrideClassLoader) {
@@ -768,7 +811,7 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen
* @see org.hibernate.cfg.Configuration#Configuration()
*/
protected Configuration newConfiguration() throws HibernateException {
- return (Configuration) BeanUtils.instantiateClass(this.configurationClass);
+ return BeanUtils.instantiateClass(this.configurationClass);
}
/**
@@ -891,12 +934,15 @@ public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implemen
logger.info("Dropping database schema for Hibernate SessionFactory");
HibernateTemplate hibernateTemplate = new HibernateTemplate(getSessionFactory());
hibernateTemplate.execute(
- new HibernateCallback() {
+ new HibernateCallback