Search code examples
javaspringspring-mvccachinginvalidation

Automatic cache invalidation in Spring


I have a class that performs some read operations from a service XXX. These read operations will eventually perform DB reads and I want to optimize on those calls by caching the results of each method in the class for a specified custom key per method.

Class a {

    public Output1 func1(Arguments1 ...) {
    ...
    }

    public Output2 func2(Arguments2 ...) {
    ...
    }

    public Output3 func3(Arguments3 ...) {
    ...
    }

    public Output4 func4(Arguments4 ...) {
    ...
    }
}

I am thinking of using Spring caching(@Cacheable annotation) for caching results of each of these methods.

However, I want cache invalidation to happen automatically by some mechanism(ttl etc). Is that possible in Spring caching ? I understand that we have a @CacheEvict annotation but I want that eviction to happen automatically.

Any help would be appreciated.


Solution

  • According to the Spring documentation (section 36.8) :

    How can I set the TTL/TTI/Eviction policy/XXX feature?

    Directly through your cache provider. The cache abstraction is... well, an abstraction not a cache implementation. The solution you are using might support various data policies and different topologies which other solutions do not (take for example the JDK ConcurrentHashMap) - exposing that in the cache abstraction would be useless simply because there would no backing support. Such functionality should be controlled directly through the backing cache, when configuring it or through its native API.@

    This mean that Spring does not directly expose API to set Time To Live , but instead relays on the caching provider implementation to set this. This mean that you need to either set Time to live through the exposed Cache Manager, if the caching provider allows dynamic setup of these attributes. Or alternatively you should configure yourself the cache region that the Spring is using with the @Cacheable annotation.

    In order to find the name of the cache region that the @Cacheable is exposing. You can use a JMX console to browse the available cache regions in your application.

    If you are using EHCache for example once you know the cache region you can provide xml configuration like this:

    <cache name="myCache"
          maxEntriesLocalDisk="10000" eternal="false" timeToIdleSeconds="3600"
          timeToLiveSeconds="0" memoryStoreEvictionPolicy="LFU">
    </cache>
    

    Again I repeat all configuration is Caching provider specific and Spring does not expose an interface when dealing with it.

    REMARK: The default cache provider that is configured by Spring if no cache provider defined is ConcurrentHashMap. It does not have support for Time To Live. In order to get this functionality you have to switch to a different cache provider(for example EHCache).