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
.