spring-bootehcachespring-cachejcachejsr107

Cache key issues with Jcache


I am using JSR107 caching with Springboot. I have following method.

@CacheResult(cacheName = "books.byidAndCat")
public List<Book> getAllBooks(@CacheKey final String bookId, @CacheKey final BookCategory bookCat) {

return <<Make API calls and get actual books>>
}

First time it makes actual API calls, and second time it loads cache without issue. I can see the following part of log.

Computed cache key SimpleKey [cb5bf774-24b4-41e5-b45c-2dd377493445,LT] for operation CacheResultOperation[CacheMethodDetails ...

But the problem is I want to load cache without making even first API call, Simply needs to fill the cache like below.

String cacheKey  = SimpleKeyGenerator.generateKey(bookId, bookCategory).toString();     
        cacheManager.getCache("books.byidAndCat").put(cacheKey, deviceList);

When I am checking, hashcode of cachekeys are same in both cases, But it is making API calls. If the hashcode is same in both cases, why it is making API calls without considering the cache ?

When debugging spring classes identified that, org.springframework.cache.interceptor.SimpleKeyGenerator is used with the cache key generation even @CacheResult is there. EDIT and enhance the question :

Apart from that if getAllBooks has overloaded methods, and then call this cached method via separate overloaded method, in that case also method caching is not working.


Solution

  • As @Henri suggested, we can use the cacheput. But for that we need methods. With the below we can update the cache very similar to the cacheput,

    //overloaded method both id and cat is available.

    List<Object> bookIdCatCache = new ArrayList<>();
        bookIdCatCache.add(bookId);
        bookIdCatCache.add(deviceCat);
        Object bookIdCatCacheKey  = SimpleKeyGenerator.generateKey(bookIdCatCache.toArray(new Object[bookIdCatCache.size()]));
        cacheManager.getCache("books.byidAndCat").put(bookIdCatCacheKey , bookListWithIdAndCat);
    

    //overloaded method only id is there

    List<Object> bookIdCache = new ArrayList<>();
            String nullKey          = null
            bookIdCache.add(bookId);
            bookIdCache.add(nullKey);
            Object bookIdCacheKey  = SimpleKeyGenerator.generateKey(bookIdCache.toArray(new Object[bookIdCache.size()]));
            cacheManager.getCache("books.byidAndCat").put(bookIdCacheKey , bookListWithId);
    

    //Not correct(My previous implementation)

    String cacheKey  = SimpleKeyGenerator.generateKey(bookId, bookCategory).toString();
    

    //Correct(This is getting from spring)

    Object cacheKey  = SimpleKeyGenerator.generateKey(bookIdCatCache.toArray(new Object[bookIdCatCache.size()]));