Reputation: 4061
Given I have Spring Data repository and I put Cacheable annotation on findAll
method:
@Repository
@CacheConfig(cacheNames = TEMPLATE_CACHE)
public interface TemplateRepository extends JpaRepository<Template, Long> {
@Override
@Cacheable
List<Template> findAll();
}
Intellij IDEA show warning:
Spring Team recommends that you only annotate concrete classes (and methods of concrete classes) with the @Cache* annotation, as opposed to annotating interfaces.
You certainly can place the @Cache* annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies.
The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies (proxy-target-class="true") or the weaving-based aspect (mode="aspectj"),
then the caching settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a caching proxy, which would be decidedly bad.
Is it really that bad?
What could happen from practical point of view?
Where should I put that annotation given I want to call findAll
in e.g. Controller
mapping?
How does Spring Data handle this? It seems to be working fine for me.
Upvotes: 15
Views: 10472
Reputation: 114
As others have stated here, it's best to have a layer that you use to get data from your repository.
Under that service layer, you will add your cache annotations. When you do things in a somewhat unexpected way, you will find that Spring's proxies do not function as intended.
The Cacheable annotation (to the best of my knowledge) relies on weaving to function. Your call to a method is intercepted via the Spring Framework to provide a cache function. If no cache hit exists, it will continue to run the method.
Here's why it's important to put the Cacheable annotation in the right spot: You can call a cached method within the same class, but the cache will not actually be called, because of weaving.
Spring can't intercept calls in the same class. Putting it on a repository interface can certainly cause issues since Spring provides the concrete implementation via whatever Spring Data package you are using, which is why they provide that warning.
A very brief explanation: https://ducmanhphan.github.io/2019-02-19-How-Spring-Caching-mechanism-works/
Detailed info from Spring themselves: https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#cache
Upvotes: 2