My team has been using the @Cachable annotation in Spring and caching Optional<> in Java. We just upgraded to Spring 4.3 and started getting errors because or caches do not allow nulls and Spring was unwrapping the Optional and attempting to put in null when it was empty.
I tried looking in the docs but I could not find anywhere that explains how Spring behaves when it goes to the cache, finds null and is supposed to return an Optional<>. Can anyone provide some context; will it convert it to an empty Optional or will it throw any error?
To enable caching, Spring makes good use of annotations, much like enabling any other configuration level feature in the framework. Note: After we enable caching, for the minimal setup, we must register a cacheManager.
Spring provides two ways to evict a cache, either by using the @CacheEvict annotation on a method, or by auto-wiring the CacheManger and clearing it by calling the clear() method.
As the name implies, @Cacheable is used to demarcate methods that are cacheable - that is, methods for whom the result is stored into the cache so on subsequent invocations (with the same arguments), the value in the cache is returned without having to actually execute the method.
Annotation Interface Cacheable. Annotation indicating that the result of invoking a method (or all methods in a class) can be cached. Each time an advised method is invoked, caching behavior will be applied, checking whether the method has been already invoked for the given arguments.
A little bit late, I know. I found this question looking for the same problem.
I am not a native english speaker and was confused by the meaning of "unless". In the end I managed to solve it doing the opposite @Anand suggested:
unless = "#result == null"
like so:
@Cacheable(value = "clients", key = "#p0.concat(#p1)", unless = "#result == null")
Optional<Client> findByClientAndProfile(String idClient, String profile);
Support for Optional was added to the Spring Cache Abstraction around version 4.3.3.RELEASE See the Conditional Caching section of this for an example.
The cache abstraction supports java.util.Optional, using its content as cached value only if it present. #result always refers to the business entity and never on a supported wrapper so the previous example can be rewritten as follows:
@Cacheable(cacheNames="book", condition="#name.length < 32", unless="#result.hardback")
public Optional<Book> findBook(String name)
Note that result still refers to Book and not Optional.
Also see this SO post.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With