Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I am trying to write an application to cache which reloads every few seconds. I decided to use spring boot Caffeine and got a sample application too. But when I am specifying refreshAfterWrite property, it throws exception: refreshAfterWrite requires a LoadingCache

spring:
    cache:
        cache-names: instruments, directory
        caffeine:
            spec: maximumSize=500, expireAfterAccess=30s, refreshAfterWrite=30s

To resolve this I provide Loading Cache Bean, but cache stopped working altogether:

@Bean
    public CacheLoader<Object, Object> cacheLoader() {
        return string -> {
            System.out.println("string = " + string);
            return string;
    @Bean
    public LoadingCache<Object, Object> loader(CacheLoader<Object, Object> cacheLoader) {
        return Caffeine.newBuilder()
                .refreshAfterWrite(1, TimeUnit.SECONDS)
                .build(cacheLoader);

Do we have some simple way for reload to work?

Spring Cache abstraction provides implementers with only get(key, function), but that means the function could change. To refresh automatically, Caffeine expects a function upfront to call but that can't be provided by Spring's abstraction. Their recommendation is that their abstraction is for the simple / common case and, rather than enhance it to support more complex scenarios, users should prefer using the native APIs instead. – Ben Manes Dec 6, 2018 at 20:42 Are you using this Cache with the cache abstraction? If so, what is the use case to refresh the cache after 30s since the intent is that the method invocation is the one that is responsible to fetch the data if necessary? If you just add an expiration, the cache abstraction will call the method you've annotated the next time you try to access the data and the cache entry expired. – Stephane Nicoll Dec 10, 2018 at 9:07 Hi @StephaneNicoll, the use-case is to reload the data change every 30 sec, and keep it cached, so that when we receive the request after 30 sec, it should pick up to date from cache directly. Otherwise every 30sec, the cache will expire and the next request will have to load the data again, and so that call will take time. The main idea to keep the data precompiled and avoid runtime call. – krmanish007 Dec 10, 2018 at 11:05 You shouldn't be using the cache abstraction then. If you're loading the cache yourself, you are duplicating what the cache abstraction already does. When you flag a method @Cacheable you're teaching the infrastructure what it should call when an entry is missing. – Stephane Nicoll Dec 10, 2018 at 13:13 our requirement too is to load the data when the cache is missing (exactly what @Cacheable does), and whatever we have already cached, should keep refreshing every 30 sec. So, its a mix of 2 different patterns, which is supported in Caffeine but in its native implementation. – krmanish007 Dec 10, 2018 at 13:42

To conclude here, using the LoadingCache feature of Caffeine with Spring's cache abstraction does not make much sense since they share a lot of features.

@Cacheable typically provide a way to mark a method to retrieve an element that is not present in the cache yet. LoadingCache achieves the same scenario, requiring you to provide a handle that can load a missing element by id.

If you absolutely need to use a LoadingCache, I'd inject the Cache in your code and interact with it programmatically.

I think this is a legitimate bug/enhancement on Spring Boot side. Spring Boot already supports "expireAfterWrite" abstraction. There is no reason not to support "refreshAfterWrite" the same way. Under the hood of abstraction, it's a different way to call Caffeine API. "refreshAfterWrite" needs a Caffeine cache loader (and is currently missing). The abstraction should be "translating" the very same user method that is being annotated by @Cacheable into the cache loader for the underlying Caffeine cache. In that sense, it is exactly the kind of "abstraction" Spring Boot aims to provide. – q3769 Aug 24, 2021 at 17:58

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.