I want to do something with ehcache in Java that I think should be extremely simple, but I\'ve spent enough time frustrating myself with the docs...
Write a
this might be a little late but i had the same problem: what helped was to shutdown the cache manager.
(from the docu: http://ehcache.org/documentation/code-samples#ways-of-loading-cache-configuration)
Shutdown the singleton CacheManager:
CacheManager.getInstance().shutdown();
Shutdown a CacheManager instance, assuming you have a reference to the CacheManager called :
manager.shutdown();
This took me a while to figure out, but basically what needs to be done here is creating the CacheManager accordingly.
If you create the cache manager and the caches the same way how you created it in the xml it will work.
net.sf.ehcache.CacheManager manager = net.sf.ehcache.CacheManager
.create(new Configuration().diskStore(
new DiskStoreConfiguration().path("C:/mycache")
)
.cache(new CacheConfiguration()
.name(testName)
.eternal(true)
.maxBytesLocalHeap(10000, MemoryUnit.BYTES)
.maxBytesLocalDisk(1000000, MemoryUnit.BYTES)
.diskExpiryThreadIntervalSeconds(0)
.diskPersistent(true)));
I think you should remove the manager.cacheExists(..)
test and simply create your cache using testCache = manager.getCache("test");
instead of using new Cache(..)
. Even if your cache is diskPersistent, it won't exist until you get it the first time. (At least that's what I think as I'm only using getCache(..)
and it does exactly what you are looking for)
Note:
You could also add something like this to make sure the cache exists:
Cache cache = manager.getCache(name);
if (cache == null) {
throw new NullPointerException(String.format("no cache with name %s defined, please configure it in %s", name, url));
}
Note 2:
If your configuration file is called ehcache.xml, you shouldn't use I think I've confused using CacheManager.create(url)
. Instead use the CacheManager singleton:CacheManager.create(url)
with and using new CacheManager(url)
. Still, you should use the singleton for ehcache.xml
and new CacheManager(url)
for anything else.
// ehcache.xml - shared between different invocations
CacheManager defaultManager = CacheManager.getInstance();
// others - avoid calling twice with same argument
CacheManager manager = CacheManager.create(url);
Using CacheManager.create(..)
is problematic as it might completely ignore the passed URL if any of the create(..)
methods or getInstance()
have been called before:
public static CacheManager create(URL configurationFileURL) throws CacheException {
synchronized (CacheManager.class) {
if (singleton == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Creating new CacheManager with config URL: " + configurationFileURL);
}
singleton = new CacheManager(configurationFileURL);
}
return singleton;
}
}
That's why I wouldn't recommend using any of the CacheManager.create(..)
methods. Use CacheManager.getInstance()
or new CacheManager(url)
.
I suppose this will work, but I still wonder why programatically defined caches can't persist on disk (especially since they are still written to disk!)
My understanding is that a programmatically created cache (i.e. not declared in ehcache.xml
) can use a DiskStore
that can itself be persistent but this doesn't mean that this cache will be loaded automatically by the CacheManager
uppon restart. Actually, I don't think the previously mentioned files do contain the cache parameters.
But, if you "recreate" the cache programmatically with the same parameters, you'll find the previously cached entries back from the DiskStore
.
Okay, well what I did to fix this was configure my cache using the configuration file. Here is the updated config:
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<diskStore path="C:/mycache" />
<defaultCache
maxElementsInMemory="10000"
eternal="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU" />
<cache
name="test"
maxElementsInMemory="500"
eternal="true"
overflowToDisk="true"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="1"
memoryStoreEvictionPolicy="LFU" />
</ehcache>
So basically I didn't use the constructor to define the cache.
I suppose this will work, but I still wonder why programatically defined caches can't persist on disk (especially since they are still written to disk!).
Thanks for the comments guys.
Small hint if your cache on disk stays empty: Be sure your elements in the cache are serializable. ehcache does log if thats not the case but my log settings did not print out these log entries.