Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ehcache - using SelfPopulatingCache when data is not present

Tags:

java

ehcache

I am using the EhCache's decorator SelfPopulatingCache and have an issue when the cache tries to load a new entry, but it's non-existent (i.e. it doesn't exist in the database). So the cache will put a null value into the cache, to unblock any other gets on the key, but then the next thread will do the same database call because it received 'null' from the cache. which means it thinks the entry needs to be loaded - even though in reality it's null because the data doesn't exists anywhere. I feel like I'm doing something wrong.

(pseudo code)

Value v = cache.get(key); // multiple threads will block here
if (v == null)
   cache.put(key, getValueFromDB()); // this might put a null value

My current solution is to not put null, but to put a placeholder Object and check for it.

Value v = cache.get(key);
if (v == null)
   cache.put(key, getValueFromDB());
else if (v == NOENTRYOBJECT)
   return null;
else
   return v;

Thoughts?

like image 773
Gandalf Avatar asked Dec 17 '10 18:12

Gandalf


People also ask

How to disable Ehcache?

sf. ehcache. disabled=true in the Java command line) disables caching in ehcache. If disabled, no elements can be added to a cache (puts are silently discarded).

Is Ehcache in memory cache?

1. Overview. In this article, we will introduce Ehcache, a widely used, open-source Java-based cache. It features memory and disk stores, listeners, cache loaders, RESTful and SOAP APIs and other very useful features.

Where does Ehcache store data?

Data stores supported by Ehcache include: On-Heap Store - Utilizes Java's on-heap RAM memory to store cache entries. This tier utilizes the same heap memory as your Java application, all of which must be scanned by the JVM garbage collector.

How Ehcache works in hibernate?

Ehcache as a plug-in second-level cache for Hibernate – Automatically cache common queries in memory to substantially lower latency. BigMemory for an in-memory store – Leverage off-heap physical memory to keep more of the data set close to your application and out of reach of Java garbage collection.


2 Answers

We do something similar. In our case, we enter Boolean.FALSE into the cache if the requested key doesn't correspond to a valid item. It basically tells the calling code that the key that it asked for doesn't match any data. You need to make one call to the db on the first request for that key to discover that it doesn't correspond to valid data, but subsequent calls are spared the db lookup. Of course, if data is ever entered into the db for that key, you need to be sure to invalidate that cache entry (otherwise you'll be returning Boolean.FALSE even though there is actual data available).

Not sure if my response helps that much (it's not an alternative approach), but it at least validates that you're not alone in your approach.

BTW, I don't think this is unique to EHCache's SelfPopulatingCache.

like image 106
sho222 Avatar answered Sep 19 '22 12:09

sho222


The typical pattern is not to recheck the database if the item's KEY exists in the cache at all, rather than the VALUE.

The pattern is described in the ehcache docs here: Caching Empty Values.

Typically, but not always, get returns an Element, so get(id) won't be null if put(id, value) was ever previously called, even if value is null.

Note that this depends on the cache implementation. The ehcache documentation seems to suggest that it should always work, but BlockingCache (and its descendants) does NOT allow putting null values into the cache. The base ehcache Cache object does allow null values to be stored in the cache (as do many examples and custom implementations).

In all I think the solution you already have (placeholder value object), also works and should achieve the same result as the ehcache base Cache class and documentation.

like image 43
Charlie Collins Avatar answered Sep 20 '22 12:09

Charlie Collins