2

I need to cache null values with Ehcache 3. For Ehcache 2 I found examples like here:

// cache an explicit null value:
cache.put(new Element("key", null));

Element element = cache.get("key");

if (element == null) {

// nothing in the cache for "key" (or expired) ...
} else {

// there is a valid element in the cache, however getObjectValue() may be null:

Object value = element.getObjectValue();

if (value == null) {

    // a null value is in the cache ...

} else {

    // a non-null value is in the cache ...

Are there examples for this for Ehcache 3 as it seems net.sf.ehcache.Element doesn't exist anymore?

I have also seen this comment: https://github.com/ehcache/ehcache3/issues/1607

Indeed, you cannot cache a null value, this is also the behaviour of the JCache specification. If you need this in your application, either create a sentinel value or wrap your values from your application.

Of course I could build some logic if my return object is null put it to an other Set were I store only my keys for null elements. Of course also for reading I need to check my ehcache and my "special" Set.

timguy
  • 2,063
  • 2
  • 21
  • 40

2 Answers2

5

Your question contains the answer, you need either to use the null object pattern or a related solution to wrap / hide your nulls.

There is no, and there will not be, support for null key or values in Ehcache 3.

Louis Jacomet
  • 13,661
  • 2
  • 34
  • 43
  • Thanks so far. Just thought there could be also some kind of recipe as for Ehcache2. I think I will go with something like described here: http://stackoverflow.com/questions/4473579/ehcache-using-selfpopulatingcache-when-data-is-not-present using `Boolean.FALSE or whatever in case of null. – timguy Apr 25 '17 at 13:31
  • 1
    Beware that `Optional` is not `Serializable` and so will not work for any cache beyond heap. – Louis Jacomet Apr 26 '17 at 15:53
1

I simply created a null placeholder class.

public class EHCache3Null implements Serializable {
  private static final long serialVersionUID = -1542174764477971324L;
  private static EHCache3Null INSTANCE = new EHCache3Null();

  public static Serializable checkForNullOnPut(Serializable object) {
    if (object == null) {
      return INSTANCE;
    } else {
      return object;
    }
  }

  public static Serializable checkForNullOnGet(Serializable object) {
    if (object != null && object instanceof EHCache3Null) {
      return null;
    } else {
      return object;
    }
  }
}

Then when I use the cache I have the following on my put operation:

cache.put(element.getKey(), EHCache3Null.checkForNullOnPut(element.getValue()));

and then this on my get operation:

Serializable value = EHCache3Null.checkForNullOnGet((Serializable) cache.get(key));
JonathanT
  • 366
  • 1
  • 6