EhCache default cache in java
My understanding is that the "default cache" is actually a template for new caches that get created, rather than being a specific named cache.
CacheManager.getCache
will only return a cache instance if it has already been created, so you'll need to tell it to create a new one, using something like addCacheIfAbsent()
. The name doesn't matter, it will be created on demand using the default cache settings.
I came across the same problem trying to create a new cache.
Using EhCache 2.7.3 I couldn't use the addCacheIfAbsent(..)
method since it returns the deprecated EhCache class, and not the Cache class.
My initial attempt was as follows:
private Cache addCache(Class<?> cacheClazz) {
CacheConfiguration cacheConfiguration = null;
{
Cache defaultCache = getCacheManager().getCache("default");
cacheConfiguration = defaultCache.getCacheConfiguration();
}
Cache newCache = new Cache(cacheConfiguration);
getCacheManager().addCache(newCache);
return newCache;
}
But using CacheManager.getCache("default")
returns null
- so yeah, it doesn't seem like one can get a reference to the default (template) cache.
I got the code working as follows:
private Cache addCache(Class<?> cacheClazz) {
// get the default (template) cache configuration
CacheConfiguration cacheConfiguration = getCacheManager().getConfiguration().getDefaultCacheConfiguration();
// give it a unique name or the process will fail
cacheConfiguration.setName(cacheClazz.getName());
Cache newCache = new Cache(cacheConfiguration);
getCacheManager().addCache(newCache);
return newCache;
}
It wasn't thread safe (tested using TestNg concurrent tests). The final implementation looks as follows:
private final static Map<String, String> firstRunMap = new HashMap<>(); // Not using ConcurrentHashMap so be careful if you wanted to iterate over the Map (https://stackoverflow.com/questions/27753184/java-hashmap-add-new-entry-while-iterating)
private Cache addCache(Class<?> cacheClazz) {
final String mapKey = getMapKey(cacheClazz);
if (firstRunMap.get(mapKey) == null) {
synchronized(mapKey) {
if (firstRunMap.get(mapKey) == null) {
// -----------------------------------------------------
// First run for this cache!!!
// -----------------------------------------------------
// get the default (template) cache configuration
CacheConfiguration cacheConfiguration = getCacheManager().getConfiguration().getDefaultCacheConfiguration();
// give it a unique name or the process will fail
cacheConfiguration.setName(cacheClazz.getName());
Cache newCache = new Cache(cacheConfiguration);
getCacheManager().addCache(newCache);
// -----------------------------------------------------
// First run complete!!!
// -----------------------------------------------------
firstRunMap.put(mapKey, "");
return newCache;
}
}
}
// Not the first thread
return getCache(cacheClazz);
}
// This class is AbstractEhCache - change it to your class
private String getMapKey(Class<?> cacheClazz) {
String mapKey = AbstractEhCache.class.getName() // to differentiate from similar keys in other classes
+ "-" + cacheClazz.getName();
// Using intern() on the key as I want to synchronize on it.
// (Strings with different hashCodes represent different locks)
return mapKey.intern();
}
private Cache getCache(Class<?> cacheClazz) {
return getCacheManager().getCache(cacheClazz.getName());
}