I have a project setup (the snippets here are from a demo project I have created on GitHub https://github.com/ashishmarwal/self-populating-cache-issue) where a raw eh-cache cache is declared in the ehcache config (ehcache.xml).
<cache name="alphabet-description-cache"
eternal="false"
maxElementsInMemory="1000"
memoryStoreEvictionPolicy="LRU"
overflowToDisk="false"
timeToLiveSeconds="300"
timeToIdleSeconds="300" />
Spring bean descriptor then uses that raw cache to create a decorated (SelfPopulatingCache) using a CacheEntryFactory:
<bean id="springCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="cacheManager"/>
</bean>
<!--Creating a decorated cache instance using the raw cache cinfigured in ehcache.xml -->
<bean id="alphabetDescriptionCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager"/>
<property name="cacheName" value="alphabet-description-cache"/>
<property name="cacheEntryFactory" ref="alphabetDescriptionCacheEntryFactory"/>
</bean>
<bean id="alphabetDescriptionCacheEntryFactory" class="com.marwals.ashish.issues.selfpopulatingcache.AlphabetDescriptionCacheEntryFactory" />
We also have a test-context.xml which is used for unit testing and declares a cacheManager as well as the decorated cache (in my perspective I have given different names to these cache managers):
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="cacheManagerName" value="self-populating-cache-issue-demo-test"/>
<property name="shared" value="true"/>
<property name="acceptExisting" value="false"/>
<property name="configLocation" value="classpath:/ehcache.xml"/>
</bean>
<bean id="springCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="cacheManager"/>
</bean>
<bean id="alphabetDescriptionCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager"/>
<property name="cacheName" value="alphabet-description-cache"/>
<property name="cacheEntryFactory" ref="alphabetDescriptionCacheEntryFactory"/>
</bean>
<bean id="alphabetDescriptionCacheEntryFactory" class="com.marwals.ashish.issues.selfpopulatingcache.AlphabetDescriptionCacheEntryFactory" />
The problem here is that if I have two different tests each loading either the main or the test-context bean descriptor, I run into an incumbent cache issue:
Error creating bean with name 'alphabetDescriptionCache' defined in class path resource [test-context.xml]: Invocation of init method failed;
nested exception is net.sf.ehcache.CacheException: Cannot replace alphabet-description-cache It does not equal the incumbent cache.
Any ideas what could be wrong here? Debugging the code reveals that I have two different cache instance for the same raw cache which is then raised as an error by EhCache's cache manager.
I have created a git repo demonstrating this problem: https://github.com/ashishmarwal/self-populating-cache-issue
Thanks!!!
You explicitly requested a shared cache manager in your Spring configuration
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="cacheManagerName" value="self-populating-cache-issue-demo"/>
<property name="shared" value="true"/> <!-- here -->
<property name="acceptExisting" value="false"/>
<property name="configLocation" value="classpath:/ehcache.xml"/>
</bean>
This means Ehcache will always return the same CacheManager
for a given configuration. In your case (and generally) you don't want that.
Just setting shared
to false
solves your problem.