Performance Zone is brought to you in partnership with:

Senior Java developer, one of the top stackoverflow users, fluent with Java and Java technology stacks - Spring, JPA, JavaEE. Founder and creator of http://computoser.com and http://welshare.com . Worked on Ericsson projects, Bulgarian e-government projects and large scale recruitment platforms. Member of the jury of the International Olympiad in Linguistics and the Program committee of the North American Computational Linguistics Olympiad. Bozhidar is a DZone MVB and is not an employee of DZone and has posted 84 posts at DZone. You can read more from them at their website. View Full User Profile

Be Careful With Cache Managers

01.07.2013
| 7140 views |
  • submit to reddit

If you are using spring and JPA, it is very likely that you utilize ehcache (or another cache provider). And you do that in two separate scenarios: JPA 2nd level cache and spring method caching.

When you configure your application, you normally set the 2nd level cache provider of your JPA provider (hibernate, in my case) and you also configure spring with the “cache” namespace. Everything looks OK and you continue with the project. But there’s a caveat. If you follow the most straightforward way, you get two separate cache managers which load the same cache configuration file. This is not bad per-se, but it is something to think about – do you really need two cache manager and the problems that may arise from this?

Probably you don’t. So you have to get rid of the redundant manager. To do that, you need to set your spring cache manager as shared:

<bean id="ehCacheManager"
    class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="shared" value="true" />
</bean>

This means that spring won’t create a new instance of cache manager, but will reuse the one already created by hibernate. Now, there’s something to think about here – it would depend on the order of bean creation – whether the JPA factory bean or the cache manager factory bean will be first. Luckily, this doesn’t matter for the end result, because SingletonEhCacheRegionFactory reuses an existing cache manager instance if it finds one.

So, now you have made your cache manager jvm-singleton. But then there’s another problem that you may encounter if you have multiple applications deployed and you are using JMX. The Cache manager registers itself as a JMX bean. But when you have singletons, multiple applications will try to register the same cache manager multiple times, and that will fail. The result will be a couple of exceptions in the log and the inability to control the cache manager of multiple modules. A side effect of the same problem gets in the way if you use something like Terracotta (there cache manager identity matters). Luckily, you have an easy fix for that. Just add one property to the bean definition shown above:

<property name="cacheManagerName" value="${module.name}" />

${module.name} is a property resolved with a PropertyPlaceholderConfigurer and is configurable per webapp, so each webapp can have a different module name. That way the cache manager will be accessible under the specified name via JMX.

Overall, be careful with your cache managers. Even in case you are using different cache, jpa and DI provider, you should verify the scenarios described above.


Published at DZone with permission of Bozhidar Bozhanov, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)