Have you ever wanted to use caching in your Spring/Hibernate application beyond just supporting Hibernate’s 2nd-level cache?

If you know what a Hibernate 2nd-level cache is, you really know how huge its performance benefits are. Wouldn’t it be useful to utilize caching for other things in your application? Even if you don’t explicitly use a caching API in your app, you still might already be using caching without knowing it – other open source frameworks in addition to Hibernate utilize caching internally for the same performance benefits.

This article explains how to achieve the following:

1) I know I’m going to utilize caching for Hibernate’s 2nd-level cache, but I want to enable that same caching support to other libraries and frameworks that might need it. It would also nice to have if I ever need to use it in my own application code directly.

2) My application is Spring-configured, so I want to configure that caching support in Spring like everything else and then have all the frameworks/libraries, including Hibernate, to use these Spring-configured cache beans.

Unfortunately Hibernate makes this a pain to do.

Hibernate uses something called a CacheProvider to support its 2nd-level cache. A Hibernate SessionFactory uses a single CacheProvider to maintain/manage the individual Cache instances used by the 2nd-level cache.

Now here’s the problem: This CacheProvider is instantiated by Hibernate based on text configuration properties specified to the SessionFactory. When the SessionFactory starts up, it reads these properties, finds the one called hibernate.cache.provider_class which specifies a fully-qualified class name of the CacheProvider implementation, and creates a new instance of that class via reflection. It then uses that instance from then on to manage the Cache instances it needs.

For existing spring configs, here is a simplified example (note the 2nd hibernate property):


hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.cache.provider_class = net.sf.ehcache.hibernate.EhCacheProvider

Why is this a problem? Because you can’t easily configure your CacheProvider instance yourself and then just tell the SessionFactory to use it. The SessionFactory interface and its default implementation do not have setter methods that would allow you to do so. This means you can’t use Dependency-Injection to set the CacheProvider instance on the Hibernate SessionFactory in Spring or any other DI microcontainer.

This is a problem for me too. The scenario that prompted this article happens to me quite a bit – I use Hibernate plus other libraries that benefit from caching. My own open-source project, Apache Shiro, can use caching to greatly speed up security checks. When I use Hibernate and Shiro in the same application, I want both frameworks to use the same underlying cache infrastructure. And although Shiro supports DI for its cache support, Hibernate does not, which means I have to jump through hoops to get Hibernate to play nice.

Where does Ehcache come in to this? Well, Ehcache is one of the more well-known and stable open-source caching solution for enterprise applications. It is stable and has a long history, it is extremely efficient with goodies like smart multi-threading under the hood, and now with Ehcache 1.3+, supports multicast distributed caching in a cluster – a huge benefit in enterprise apps. Basically, for open-source options, it is one of the best you can get. Cheers to Greg Luck for creating and supporting this great library (Another wonderful Open Source alternative is TerraCotta, take a look at that too).

So, in this particular example, I’m using EhCache but I also want to use it not just for Hibernate, but for Shiro and everything else that could use a Cache. And until now, I’ve been using Ehcache as Hibernate’s cache provider using the aforementioned text property. Hibernate would create an instance of EhCacheProvider and use it internally. Basically this EhCacheProvider implementation is a wrapper around EhCache’s own API of a CacheManager.

The CacheManager is really what I want to configure in Spring. Typically it is good practice and much easier to specify a single CacheManager for an application, which uses a single ehcache.xml file for all configuration. Then you can use this one ehcache.xml file for your Hibernate cache configuration, as well as for any other library that would use EhCache under the hood.

So, since you can’t inject a CacheManager into Hibernate’s SessionFactory, how do you do this in Spring?

Well, Since Hibernate instantiates the CacheProvider itself, and we can’t inject anything, our only option left is via static memory. Blech, I know – I don’t like statics any more than you do, but don’t worry – it is _only_ used as a mechanism to make Hibernate play nice and its never used anywhere else in your config or application code.

*Note that static memory will only allow a single CacheManager to be used across the entire VM, so if you need more than one Hibernate SessionFactory, each with its own separate cache configs, you’ll need to do more trickery (maybe 2 static fields? one per SessionFactory? You’ll know more about your app than I do, so I’ll leave how to do that to you. But you can use this the following technique and expand on it for your environment).

Let’s get to the code, its only one class. You’ll create your own CacheProvider implementation to statically reference a CacheManager instance. The CacheManager instance will be configured in Spring, and we’ll get to that in a bit. Here’s the CacheProvider implementation:

package com.leshazlewood.hibernate;

import net.sf.ehcache.CacheManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.cache.Cache;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.CacheProvider;
import org.hibernate.cache.Timestamper;

import java.util.Properties;

* @author Les Hazlewood
public class ExternalEhCacheProvider implements CacheProvider {

protected transient final Log log = LogFactory.getLog(getClass());

private static CacheManager cacheManager = null;

* This is the method that is called by an external framework (e.g. Spring) to set the
* constructed CacheManager for all instances of this class. Therefore, when
* Hibernate instantiates this class, the previously statically injected CacheManager
* will be used for all hibernate calls to build caches.
* @param cacheManager the CacheManager instance to use for a HibernateSession factory using
* this class as its cache.provider_class.
public static void setCacheManager(CacheManager cacheManager) {
ExternalEhCacheProvider.cacheManager = cacheManager;

public Cache buildCache(String name, Properties properties) throws CacheException {
try {
net.sf.ehcache.Ehcache cache = cacheManager.getEhcache(name);
if (cache == null) {
if ( log.isWarnEnabled() ) {
log.warn( "Unable to find EHCache configuration for cache named [" + name + "]. Using defaults.");
cacheManager.addCache( name );
cache = cacheManager.getEhcache(name);
if (log.isDebugEnabled()) {
log.debug("Started EHCache region '" + name + "'");
return new net.sf.ehcache.hibernate.EhCache(cache);
} catch (net.sf.ehcache.CacheException e) {
throw new CacheException(e);

public long nextTimestamp() {
return Timestamper.next();

public void start(Properties properties) throws CacheException {
//ignored, CacheManager lifecycle handled by the IoC container

public void stop() {
//ignored, CacheManager lifecycle handled by the IoC container

public boolean isMinimalPutsEnabledByDefault() {
return false;

Ok, now that you have this class, what do you do with it? Well the first thing is to change your hibernate.cache.provider_class value to now be com.leshazlewood.hibernate.ExternalEhCacheProvider in your Hibernate SessionFactory bean definition. Then you want to define your CacheManager instance as a bean in your Spring config. Next you want to tell this CacheProvider implementation to use that instance when Hibernate needs to use caching functions.

We do that via a cool little Spring trick – by using the MethodInvokingFactoryBean. Basically this bean will call a static method at application startup with specified method arguments. Its a handy little tool that we can use to statically call the setter method that makes the CacheProvider work:


So the above spring config says: At application startup, create the CacheManager instance named ‘ehcacheCacheManager’ and then inject it into the ExternalEhCacheProvider via that class’s ‘setCacheManager’ static method.

But are we finished?

Well, not quite. We have one piece of cleanup work to do.

The experienced Spring folks will recognize that there can possibly be a race condition with our Hibernate SessionFactory and CacheManager/CacheProvider definitions. Yes, our Spring-configured CacheManager instance will be created and injected into the ExternalEhCacheProvider class correctly, and our Hibernate SessionFactory bean instance will be created correctly. But, what if the Hibernate SessionFactory tries to use a ExternalEhCacheProvider instance before it is ready to be used? (i.e. before the static CacheManager property has been injected?)

To prevent this race condition and guarantee that the ExternalEhCacheProvider’s internal CacheManager instance is set so it is available when the Hibernate SessionFactory needs it, we use the spring bean ‘depends-on’ attribute in our SessionFactory definition:


hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.cache.provider_class = com.leshazlewood.hibernate.ExternalEhCacheProvider

So, although our Hibernate SessionFactory bean doesn’t actually use the CacheManager as a property – otherwise this whole article would be pointless ;) – we force it to wait until the cacheProviderCacheManagerInjector bean has done its work before we allow it to initialize.

We make the ‘depends-on’ attribute point to this injector (MethodInvokingFactoryBean) instance specifically (as opposed to the ehcacheCacheManager bean) because we care that it is not only created, but also injected too.

There. Now we’re done. :)

Now when the Hibernate SessionFactory bean starts up and creates its hibernate.cache.provider_class instance, we can rest assured that it will access our Spring-configured CacheManager.

And, you’ll be able to use that same Spring-configured ‘ehcacheCacheManager’ bean and inject it into Shiro, or any other framework that supports simple Dependency Injection. Because this bean is an application singleton and uses a single config file, now all of your caching config across the entire application is easily manged from the same location – very convenient.

Have fun!