kolinunlt
kolinunlt

Reputation: 345

@Cacheable and @CachePut different return type

(Will Spring's @CachePut annotation work with a void return type?)

I encountered the same problem

Because the problem has been for a long time, I do n’t know if there is a solution

created a cache:

public static final String Key = "CacheKey";

@Cacheable(cacheNames = "userCache", key = "Key")
public List<User> getAllUsers() {
...
}

update this cache using the @CachePut

@CachePut(cacheNames = "userCache", key = "Key")
public User addUser(User user) {
...
}

output:

com.example.demo.dto.UserDTO cannot be cast to java.util.List

I searched for information for several days, but did not find the answer

In addition to using @CacheEvict (cacheNames = userCache, allEntries = true)

Is there a way to solve it using @Cacheable and @CachePut?

Thank you

Upvotes: 0

Views: 2453

Answers (1)

b3tuning
b3tuning

Reputation: 347

I suggest reading up on how Spring Cache Abstraction works. https://docs.spring.io/spring-framework/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/cache.html

Very basically, caches are essentially key-value stores.. For the same parameters passed into a method, check the cache and return the cached result. If the method is void, there is nothing to cache. @CachePut needs a 'value' to pair with the 'key'. If you want to cache the users added, addUser needs to return a User. Or have addUser call another method and move the @CachePut to that method.

Another issue you're facing, is your userCache from getAllUsers is List<User> and you're intending (although not working because of void) to put a User into the same cache that is expecting a List<User>

To put it another way, when you addUser, your userCache of List is now not in sync with the actual state of the result of getAllUsers so you need to evict the userCache of List

Change @CachePut(cacheNames = "userCache", key = "Key")

to @CacheEvict(cacheNames = "userCache", allEntries = true ) When you addUser, you will clear out your List cache, and next time you call getAllUsers, the cache will be updated with the now current result set.

This post is pretty much a duplicate of https://stackoverflow.com/a/59361298/3625077 where Federico touches on a point that this is a common misunderstanding. The Cached value, is not an object that can be operated on, ie. in your case, you can't .add(user) to the userCache. It's basically a snapshot of the input/output of a method.

Upvotes: 1

Related Questions