Spring Cache - Part 3 - Conditional Cache


In this part of the tutorial, we will see how data can be cached conditionally. (If you haven't checked the previous parts, please visit Part 1 and Part 2. They contain sample code that the examples below refer)

condition attribute


By providing a SPEL expression in the condition attribute, one can conditionally enable cache on a given method.
  • When the method is invoked, the condition is first evaluated against the input parameters.
  • If it evaluates to true, then the cache is looked up to check if the data with the given key exists.
  • If the data exists, it is returned.
  • If data does not exist, then the method is executed and the result is stored in the cache against the key.
  • If the condition evaluates to false, then the cache lookup is skipped and the method is executed.

Consider the example

    //This would add the result to the cache, only if the key matches "Sean Connery"
    @Cacheable(value="actors", key="#key", condition="#key == 'sean'")
        public Actor getActors(String key) {
            System.out.println("getting " + key);
            if(key.equals("sean")) {
                return new Actor("Sean Connery", Gender.MALE);
            }
            else {
                return new Actor("Meryl Streep", Gender.FEMALE);
            }
        }


Running this test code below
 service.getActors("sean");
 service.getActors("meryl");
 service.getActors("sean");
 service.getActors("meryl");

will result in the following. Notice that "getting sean" is printed only once
getting sean
getting meryl
getting meryl

Here is one more example of the condition attribute.

    //It will cache only if the actor's age is more than 20. Here actor is the input parameter.
    @Cacheable(value="movies", key="#actor.name", condition="#actor.age > 20")
    public List<movie> getMovies(Actor actor) ...

unless attribute


There is another way to perform a conditional cache, that is, using the unless attribute. Unlike the conditional attribute, unless expressions are evaluated after the method execution. Which means you would also have access to the result to construct the unless expressions.
  • When the method is invoked, the cache is looked up to check if the data with the given key exists.
  • If the data exists, it is returned.
  • If data does not exist, then the method is executed
  • After method execution, if the unless expression evaluates to true, then the data is cached, else it is not cached.

Here are a few examples with unless.

    //It will cache only if the size of the result is more than 20.
    @Cacheable(value="movies", key="#actor.name", unless="#result.size > 20")
    public List<movie> getMovies(Actor actor) ...
    //It will cache only if the input parameter is 'sean'
    @Cacheable(value="actors", key="#key", unless="#key == 'Sean Connery'")
    public Actor getActors(String key) {


2 comments: