Custom CacheProvider for Hibernate based on Websphere DistributedMap

Hibernate is a library that maps database tables to Java objects. Is performance problems arise it's very easy to add database caching for application using Hibernate (just few options in config file). Hibernate is shipped with EHCache, default cache implementation. It works well and is easy to setup.

Sometimes you have to use another caching library that has no direct support for Hibernate. Here the Hibernate API comes into play. I'll show you how to plug Websphere's DistributedMap into Hibernate.

First: you have to map get/put requests into desired API. org.hibernate.cache.Cache is an interface that must be subclassed for this task. This class instance is created by Hibernate for every entity that will be cached (distinguished by regionName).

public class WebsphereCacheImpl implements Cache {
    private DistributedMap map;
    private String regionName;
    public WebsphereCacheImpl(DistributedMap map, String regionName) {
        this.map = map;
        this.regionName = regionName;
    }
    public void clear() throws CacheException {
        map.clear();
    }
    public Object get(Object key) throws CacheException {
        return map.get(getMapKey(key));
    }
    public String getRegionName() {
        return regionName;
    }
    public void put(Object key, Object value) throws CacheException {
        map.put(getMapKey(key), value);
    }
    public Object read(Object key) throws CacheException {
        return map.get(getMapKey(key));
    }
    public void remove(Object key) throws CacheException {
        map.remove(getMapKey(key));
    }
    public void update(Object key, Object value) throws CacheException {
    map.put(getMapKey(key), value);
    }
    private String getMapKey(Object key) {
        return regionName + "." + key;
    }
    (...)
}

Then you have to prepare factory for such obejcts:

public class WebsphereCacheProviderImpl implements CacheProvider {

    private DistributedMap distributedMap;

    public WebsphereCacheProviderImpl() throws NamingException {
        InitialContext ic = new InitialContext();
        distributedMap = (DistributedMap) ic.lookup("services/cache/cache1");
    }
    public Cache buildCache(String regionName, Properties arg1) throws CacheException {
        return new WebsphereCacheImpl(distributedMap, regionName);
    }
    public boolean isMinimalPutsEnabledByDefault() {
        return false;
    }
    public long nextTimestamp() {
        return new Date().getTime();
    }
    public void start(Properties arg0) throws CacheException {
    }
    public void stop() {
    }
}

Then new factory class must be registered in Hibernate configuration:

<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="cache.provider_class">com.company.project.cache.WebsphereCacheProviderImpl</property>

And voila!

This entry was posted in en and tagged , , . Bookmark the permalink.

6 Responses to Custom CacheProvider for Hibernate based on Websphere DistributedMap

  1. Anonymous says:

    Hi Dariusz,

    Ihave created a Custom CacheProvider for Hibernate based on Websphere DistributedMap. At server startup, so good, but my problem is: buildCache method is never called.

    An idea or help

    Thank you in advance.

  2. dariusz.cieslak says:

    Probably proper XML configuration is missing in your case. Hibernate need to know what cache provider should be instantiated.

  3. Pradeep says:

    Hi I am also facing the same problem. I have these set in my Application-Context.xml

    true
    MyCacheProvider

    But when i tried to use the SecondLevelCache, the BuildCache method is not at all called. Do i need to give any other configuration ?

    Thanks,
    Pradeep.

  4. Pradeep says:

    I am sorry for the above typo.. I have set these in my Application-context.xml

    key="hibernate.cache.use_second_level_cache" = true
    key="hibernate.cache.provider_class" = com.googlecode.hibernate.memcached.MemcachedCacheProvider

    Thanks,
    Pradeep

  5. Sanjib says:

    Does it work with Hibernate4, as it does not have CacheProvider?
    Do you have any implementation with RegionFactory?

  6. dariusz.cieslak says:

    No, I haven't re-implemented it with RegionFactory as I switched temporarily to different execution environment (C++) :-). I hope I'll be back in Java world soon.

Comments are closed.