Ehcache - using SelfPopulatingCache when no data

I use the EhCache SelfPopulatingCache decorator and have a problem when the cache tries to load a new record, but it does not exist (i.e. it does not exist in the database). That way, the cache will put the null value in the cache to unlock any other key, but then the next thread will make the same database call because it received "zero" from the cache. this means that he thinks the record should be loaded - although in fact it is empty because the data does not exist 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 not to put a zero, but to put a placeholder Object and test it.

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

Thoughts?

+6
java ehcache
source share
3 answers

We are doing something similar. In our case, we Boolean.FALSE into the cache if the requested key does not match the actual element. It basically tells the calling code that the requested key does not match any data. You need to make one call to db at the first request for this key to find that it does not match the actual data, but subsequent calls are spared the search for db. Of course, if data has ever been entered in db for this key, you must be sure that you would invalidate the entry in this cache (otherwise you will return Boolean.FALSE, even if there is actual data).

I’m not sure that my answer helps a lot (this is not an alternative approach), but it at least confirms that you are not alone in your approach.

By the way, I don't think this is unique to EHCache SelfPopulatingCache.

+3
source share

A typical template does not double-check the database if the KEY element exists in the cache at all, and not VALUE .

The template is described in ehcache docs: Caching Null Values .

As a rule, but not always, get returns an Element , so get(id) will not be null if put(id, value) was previously called, even if the value is null.

Note that this depends on the implementation of the cache. The ehcache documentation seems to suggest that it should always work, but BlockingCache (and its descendants) DOES NOT allow null values ​​to be cached . The base ehcache Cache object allows you to store null values ​​in the cache (like many examples and custom implementations).

In general, I think that the solution that you already have (object-object-object) also works and should achieve the same result as the ehcache Cache class and documentation.

+1
source share

I think you need to look into the CacheElementFactory. I implemented this under spring for a project I was working on to request information about loading into the cache, if the cache was missed, an attempt was made to load it from the database. I can’t remember exactly what I did on this issue, although, I think, unfortunately, this will result in the request being sent to the database for each pass requesting for the missing key.

0
source share

All Articles