Search code examples
javaspringehcache

Spring ehCache skip caching according to a bean value


I would like to know whether it's possible to skip caching by some external condition, e.g. a bean field value.

I have the following caching method:

@Cacheable(value = "MY_CACHE", keyGenerator = "myKeyGenerator")
public List<CloudEntity> getTestMetaRecords(final String someParam) {
    ...
    return aRetrievedList;
}

What I want is to skip caching values not related to caching method. I know that there is the unless parameter inside the @Cacheable annotation, but I didn't manage to make it work. I added the following:

unless = "#myBean.getSomeValue().equals(${value.from.properties})"

Any help is much appreciated!

Update:

Ok, I've found that the unless and condition parameters can be used both for conditional caching but they use limited set of metadata in spel: methodName, method, target ... And I was able to do it only by referring the called object field via the root.target expression.

My result code is the following:

@Cacheable(value = "MY_CACHE", keyGenerator = "myKeyGenerator", condition = "#root.target.myBean.getSomeValue().equals(#root.target.valueFromProperties)")

What I don't like in this solution is that the target class with caching method have to be changed to include my dependency myBean.

Is there a more flexible solution for that?


Solution

  • I had more or less the same problem.

    In fact, the context of SpEL expression for the condition or unless props of @Cachable annotation doesn't allow retrieval of the bean from the ApplicationContext.

    However I was able to use the T() operator to retrieve the application context through a static method and then with that, I could retrieve my bean and invoke the method I needed for the condition.

    So in my case, the final SpEL expression was this:

    condition="T(my.utils.package.Registry).getApplicationContext().getBean('myBean').cachingCondition()"