0

I'm trying to do a simple test with ehcache - put an element into the cache, flush and shutdown the cache. Then reload all the beans with spring (also initializes cachemanager). Do a cache.get and retrieve previously written values.

EhCache Element's value is a some serializable class called DOM which comprises a field ConcurrentHasMap

I create 3 DOM instances: d1, d2, d3 d1 (has a map with 3 values: t1, t2, t3) d2 (has a map with 2 values: x1, x2) d3 (has a map with 2 values: s1, s2)

I call:

cachemanager and cache are created with spring
cache.put(new Element(1,d1))
cache.put(new Element(2,d2))
cache.put(new Element(3,d3))
cache.flush();
cacheManager.shutdown();
cache = null
cacheManager = null

I call to load spring application context (which creates cacheManager and cache)

I call:

actualD1 = cache.get(1)
actualD2 = cache.get(2)
actualD3 = cache.get(3)

I receive the DOM objects into the actualD1, actualD2 and actualD3 variables But the problem is that now each of them has only one value

actualD1 (has a map with 1 value: t1) actualD2 (has a map with 1 value: x1) actualD3 (has a map with 1 value: s1)

What could be the problem!???

Here is my ehcache.xml file:

<defaultCache
       maxElementsInMemory="1000000"
       eternal="false"
       diskSpoolBufferSizeMB="100"
       overflowToDisk="true"
       clearOnFlush="false"
       copyOnRead="false"
       copyOnWrite="false"
       diskExpiryThreadIntervalSeconds="300"
       diskPersistent="true">
</defaultCache>

Here is how I create a cacheManager (this method is called in startup from spring)

protected def checkAndCreateCacheManagerIfNeeded() =
{
    if (cacheManager == null)
    {
        synchronized
        {
            if (cacheManager == null)
            {
                cacheManager = CacheManager.create(ehCacheConfigFile);
            }
        }
    };
};

The following code creates the cache:

protected def getOrCreateCache(cacheName : String) =
{
    checkAndCreateCacheManagerIfNeeded();
    var cache = cacheManager.getEhcache(cacheName);
    if (cache == null)
    {
        cacheManager.synchronized
        {
            cache = cacheManager.getEhcache(cacheName);
            if (cache == null)
            {
                cache = cacheManager.addCacheIfAbsent(cacheName);
            }
        }
    };
    cache;
};
Romande
  • 561
  • 2
  • 4
  • 16

2 Answers2

1

The problem was adding t1, t2, t3 to d1 without putting the updated d1 to the cache. After each addition of the value to map. One must add the call:

cache.put(d1Element)
agf
  • 171,228
  • 44
  • 289
  • 238
Romande
  • 561
  • 2
  • 4
  • 16
0

While this isn't necessarily true, since it depends on your setup, it is considered best practice indeed to do so with Ehcache. In this particular setup, your elements are being serialized to disk (not necessarily at the time of the put though). As a result, once serialized, any subsequent change to the object graph won't reflect in the DiskStore.

This would have worked with onHeap only storage, but it is still recommended you do put back, enabling you to change the cache configuration in the future without any need to change the code.

Alex Snaps
  • 1,230
  • 10
  • 10