title: Caching on methods in JpaRepository (Spring Data)
body: <p>Tools:
  Spring-Boot : 1.5.9.RELEASE
  Spring-Data-JPA : 1.11.9.RELEASE</p>
  
  <p>Issue:
  Currently I have a repository that extended from JpaRepository. In order to avoid frequent DB access, I want to cache some of the CRUD methods in the JpaRepository.
  I tried a few ways from what I can find with Mr.Google but non of them working except one.</p>
  
  <p><strong>EDITED</strong>
   1. Solution mentioned in this <a href="https://github.com/spring-projects/spring-data-examples/blob/master/jpa/example/src/main/java/example/springdata/jpa/caching/CachingUserRepository.java" rel="nofollow noreferrer">link</a> is workable. However, there is a bad practice (redundancy to me) at here. Imagine if I have 50 repositories extending the JpaRepository, this means that I have to override the save method in 50 repositories. </p>
  
  <pre><code>     public interface UserRepository extends CrudRepository&lt;User, Long&gt; {
          @Override
          @CacheEvict("user")
          &lt;S extends User&gt; S save(S entity);
  
          @Cacheable("user")
          User findByUsername(String username);
       }
  </code></pre>
  
  <p><strong>EDITED</strong>
   2. Extend the JpaRepository interface. I saw something that might works at <a href="https://jira.spring.io/browse/DATAMONGO-1198" rel="nofollow noreferrer">link2</a>.</p>
  
  <p>In the link, it mentioned 3 different ways to caching the JpaRepository methods. the 1st method is same as what I mentioned in #1. However, I want something similar to 2nd/3rd method so that I <strong>no need to keep repeating overriding the CRUD methods in all repositories</strong>.</p>
  
  <p>Below is some sample code that I have written.</p>
  
  <pre><code>    @NoRepositoryBean        
      public interface BaseRepository&lt;T, ID extends Serializable&gt; extends 
      JpaRepository&lt;T, ID&gt; {
  
          @CacheEvict
          &lt;S extends User&gt; S save(S entity);
  
          @Cacheble
          T findOne(ID id);
      }
  
      @Repository
      @CacheConfig("user")
      public interface UserRepository extends BaseRepository&lt;User, Integer&gt; {
          // when I calling findOne/save method from UserRepository, it should 
          // caching the methods based on the CacheConfig name defined in the 
          // child class.
      }
  </code></pre>
  
  <p>However, it seems like the code (above) ain't working as I getting below exception. I understand the issue mainly happened because there is no name being assigned to the cacheable annotation in the BaseRepository. But I would need to cache the CRUD methods in the BaseRepository that extend from JpaRepository.</p>
  
  <blockquote>
    <p>java.lang.IllegalStateException: No cache could be resolved for 'Builder[public abstract java.util.List com.sdsap.app.repository.BaseRepository.findAll()] caches=[] | key='' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'' using resolver 'org.springframework.cache.interceptor.SimpleCacheResolver@30a9fd0'. At least one cache should be provided per cache operation.</p>
  </blockquote>
  
  <p>I have been asking Mr.Google for few days and yet can't find any suitable solution. I hope someone can help me at here. Sorry if my question isn't clear or missing something as this is my first time posting at here. Thanks!</p>