Alex Rivera | Logout

ehcache persist to disk issues

Asked 2009-11-13T14:37:13.983
29

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...

  1. Write a value to a disk persistent cache. Shut down.

  2. Start up again and read that value.

Here is my Java function:

private static void testCacheWrite() {

  // create the cache manager from our configuration
  URL url = TestBed.class.getClass().getResource("/resource/ehcache.xml");
  CacheManager manager = CacheManager.create(url);
  // check to see if our cache exits, if it doesn't create it
  Cache testCache = null;
  if (!manager.cacheExists("test")) {
    System.out.println("No cache found. Creating cache...");
    int maxElements = 50000;
    testCache = new Cache("test", maxElements,
      MemoryStoreEvictionPolicy.LFU, true, null, true, 60, 30,
      true, Cache.DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS, null);
    manager.addCache(testCache);
    // add an element to persist
    Element el = new Element("key", "value");
    testCache.put(el);
    testCache.flush();
    System.out.println("Cache to disk. Cache size on disk: " +
      testCache.getDiskStoreSize());
  } else {
    // cache exists so load it
    testCache = manager.getCache("test");
    Element el = testCache.get("key");
    if (null == el) {
      System.out.print("Value was null");
      return;
    }
    String value = (String) el.getObjectValue();
    System.out.println("Value is: " + value);
  }
  manager.shutdown();
}

And here is my cache configuration (ehcache.xml):

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
  <diskStore path="C:/mycache&quo
Edit
Report

2 Answers

18

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.

answered 2009-11-13T16:38:59.573
1

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 CacheManager.create(url). Instead use the CacheManager singleton: I think I've confused using 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);

        }
 
answered 2009-11-13T14:56:29.383

Your Answer