Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load @Cache on startup in spring?

I'm using spring-cache to improve database queries, which works fine as follows:

@Bean
public CacheManager cacheManager() {
    return new ConcurrentMapCacheManager("books");
}

@Cacheable("books")
public Book getByIsbn(String isbn) {
    return dao.findByIsbn(isbn);
}

But now I want to prepopulate the full book-cache on startup. Which means I want to call dao.findAll() and put all values into the cache. This routine shall than only be scheduled periodically.

But how can I explicit populate a cache when using @Cacheable?

like image 963
membersound Avatar asked Jan 14 '15 10:01

membersound


People also ask

How do you cache data during an application startup in Spring boot?

For caching at the application start-up, we can use @PostContruct in any of the Service class. This will cache the entire table data.

How do I cache a list in Spring boot?

We can enable caching in the Spring Boot application by using the annotation @EnableCaching. It is defined in org. springframework. cache.

How does Spring boot handle cache?

Spring Cache uses the parameters of the method as key and the return value as a value in the cache. When the method is called the first time, Spring will check if the value with the given key is in the cache. It will not be the case, and the method itself will be executed.


2 Answers

Just use the cache as before, add a scheduler to update cache, code snippet is below.

@Service
public class CacheScheduler {
    @Autowired
    BookDao bookDao;
    @Autowired
    CacheManager cacheManager;

    @PostConstruct
    public void init() {
        update();
        scheduleUpdateAsync();
    }

    public void update() {
        for (Book book : bookDao.findAll()) {
            cacheManager.getCache("books").put(book.getIsbn(), book);
        }
    }
}

Make sure your KeyGenerator will return the object for one parameter (as default). Or else, expose the putToCache method in BookService to avoid using cacheManager directly.

@CachePut(value = "books", key = "#book.isbn")
public Book putToCache(Book book) {
    return book;
}
like image 66
Loki Avatar answered Sep 29 '22 22:09

Loki


I have encountered the following problem when using @PostConstruct: - even though the method I wanted to be cached was called, after calling it from swagger, it still didn't use the cached value. Only after called it once more.

That was because @PostConstruct is too early for caching something. (At least I think that was the issue)

Now I'm using it more late in the startup process and it works without problems:

@Component
public class CacheInit implements ApplicationListener<ApplicationReadyEvent> {

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
       //call service method
    }

}
like image 33
Andrea Calin Avatar answered Sep 29 '22 21:09

Andrea Calin