Home > Software engineering >  How can I cache by method parameter in Spring Boot?
How can I cache by method parameter in Spring Boot?

Time:09-16

I use Redis for caching and have the following service method:

@Cacheable(value = "productCache")
@Override
public List<ProductDTO> findAllByCategory(Category category) {
    
    // code omitted 

    return productDTOList;
}

When I pass categoryA to this method, the result is cached and is kept during expiration period. If I pass categoryB to this method, it is retrieved from database and then kept in cache. Then if I pass categoryA again, it is retrieved from cache.

1. I am not sure if it is normal, because I just use value parameter ("productCache") of @Cacheable annotation and have no idea how it caches categoryA and categoryB results separately. Could you please explain how it works?

2. As mentioned on this page, there is also key parameter. But when using it as shown below, I think it does not make any sense and it works as above. Is that normal or am I missing something?

@Cacheable(value = "productCache", key="#category")
@Override
public List<ProductDTO> findAllByCategory(Category category) {
    
    // code omitted 

    return productDTOList;
}

3. Should I get cache via Cache cache = cacheManager.getCache("productCache#" category); ?

CodePudding user response:

Caches are essentially key-value stores, where – in Spring –

  • the key is generated from the method parameter(s)
  • the value is the result of the method invocation

The default key generation algorithm works like this (taken right from Spring docs):

  • If no params are given, return SimpleKey.EMPTY.
  • If only one param is given, return that instance.
  • If more than one param is given, return a SimpleKey that contains all parameters.

This approach works well for most use-cases, as long as parameters have natural keys and implement valid hashCode() and equals() methods. If that is not the case, you need to change the strategy.

So in your example, the category object acts as key per default (for this to work, the Category class should have hashCode() and equals() implemented correctly). Writing key="#category" is hence redundant and has no effect. If your Category class would have an id property, you could write key="#category.id" however.

Should I get cache via Cache cache = cacheManager.getCache("productCache#" category); ?

No, since there is no such cache. You only have one single cache named productCache.

  • Related