Reputation: 121
I encountered a strange behaviour while using @Cacheable
annotation in Spring.
I have a method marked as @Cacheable
and that returns Map:
//dao layer
@Cacheable(value = "Cache1")
public Map<String, String> getNamesByDateAndCurrency(LocalDate date, String currency) {
// Returns some map
}
I call this method from the following method and change the map using the retainAll()
method:
//service layer
@Autowired
private DaoImpl dao;
...
@Cacheable( value = "Cache2")
public List<Integer> getUUIDs(Integer requestNumber, Set<String> set) {
//some code..
Map<String, String> names = dao.getNamesByDateAndCurrency(params..);
names.keySet().retainAll(set);
//some other code, no any changes of map in further
}
dao.getNamesByDateAndCurrency(params..)
expression returns, as expected, the cached data if I call this method a second time with the same parameters.
The problem is that the getNamesByDateAndCurrency
method is caching the data changed after performing the retainAll
method.
My question is why an external action (retainAll
) method affects the cached response? Why hasn't it returned original data from getNamesByDateAndCurrency
method?
Thanks in advance!
Upvotes: 0
Views: 1529
Reputation: 5711
Spring cache stores the result in the cache by reference. Then, the caching framework used (Ehcache in your case I think) will store the result according to its configuration. Most frameworks will store it by reference by default because it is much faster.
You have 2 solutions:
Collections.unmodifiableMap
Note that whether you are storing data on the heap, on disks or clustered, it would work as expected by default. Because all these options require to copy the key and the value. Only on-heap has a "by reference" storage optimization.
Upvotes: 1