While integrating two subsystems, we were forced to use multiple SessionFactory instances, which lead to trouble when interacting with our Hibernate second-level cache (Terracotta EhCache). Specifically:
for(CacheManager cm : CacheManager.ALL_CACHE_MANAGERS){
LOGGER.log(Level.DEBUG, "In cm " + cm.getName());
for(String cn : cm.getCacheNames()){
LOGGER.log(Level.DEBUG, "I have a cache called " + cn);
LOGGER.log(Level.DEBUG, "it's status is " + ms.getCache开发者_如何转开发(cn).getStatus());
}
}
try{
myCollection.size();
}catch(IllegalStateException ise){
LOGGER.log(Level.FATAL, ise); //Triggered
}
The debug print-out shows STATUS_ALIVE
for cache "Foo" but the call to size()
throws an IllegalStateException
:
java.lang.IllegalStateException: The Foo Cache is not alive.
Currently, both SessionFactories are configured to use SingletonEhCacheRegionFactory
. If I switch the SessionFactories to use EhCacheRegionFactory
(non-singleton), what are the ramifications for cache behavior (specifically in a Web App context)?
EhCache will ensure that all instances of SingletonEhCacheRegionFactory
use the same actual CacheManager
internally, no matter how many instances of SingletonEhCacheRegionFactory
you create, making it a crude version of the Singleton design pattern.
The plain EhCacheRegionFactory
, on the other hand, will get a new CacheManager
every time.
If you have two Hibernate session factories in Spring, each using their own instance of SingletonEhCacheRegionFactory
, then they're actually going to end up sharing a lot of their cache state, which may account for your problem.
This isn't really a good match for Spring, where the singletons are supposed to be managed by the container. If you use EhCacheRegionFactory
, then you'll likely get more predictable results. I suggest giving it a go and see how you get on.
精彩评论