Search code examples
springcachingmemcached

How do I tell Spring cache not to cache null value in @Cacheable annotation


Is there a way to specify that if the method returns null value, then don't cache the result in @Cacheable annotation for a method like this?

@Cacheable(value="defaultCache", key="#pk")
public Person findPerson(int pk) {
   return getSession.getPerson(pk);
}

Update: here is the JIRA issue submitted regarding caching null value last November, which hasn't resolved yet: [#SPR-8871] @Cachable condition should allow referencing return value - Spring Projects Issue Tracker


Solution

  • Hooray, as of Spring 3.2 the framework allows for this using Spring SpEL and unless. Note from the java doc for Cacheable element unless:

    Spring Expression Language (SpEL) expression used to veto method caching. Veto caching the result if the condition evaluates to true.

    Unlike condition(), this expression is evaluated after the method has been called and can therefore refer to the result. Default is "", meaning that caching is never vetoed.

    The important aspect is that unless is evaluated after the method has been called. This makes perfect sense because the method will never get executed if the key is already in the cache.

    So in the above example you would simply annotate as follows (#result is available to test the return value of a method):

    @Cacheable(value="defaultCache", key="#pk", unless="#result == null")
    public Person findPerson(int pk) {
       return getSession.getPerson(pk);
    }
    

    I would imagine this condition arises from the use of pluggable cache implementations such as Ehcache which allows caching of nulls. Depending on your use case scenario this may or may not be desirable.