How to add cache feature in Spring Data JPA CRUDRe

2020-02-26 05:46发布

问题:

I want to add "Cacheable" annotation in findOne method, and evict the cache when delete or happen methods happened.

How can I do that ?

回答1:

virsir, there is one more way if you use Spring Data JPA (using just interfaces). Here what I have done, genereic dao for similar structured entities:

public interface CachingDao<T, ID extends Serializable> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T> {

@Cacheable(value = "myCache")
T findOne(ID id);

@Cacheable(value = "myCache")
List<T> findAll();

@Cacheable(value = "myCache")
Page<T> findAll(Pageable pageable);

....

@CacheEvict(value = "myCache", allEntries = true)
<S extends T> S save(S entity);

....

@CacheEvict(value = "myCache", allEntries = true)
void delete(ID id);
}


回答2:

I think basically @seven's answer is correct, but with 2 missing points:

  1. We cannot define a generic interface, I'm afraid we have to declare every concrete interface separately since annotation cannot be inherited and we need to have different cache names for each repository.

  2. save and delete should be CachePut, and findAll should be both Cacheable and CacheEvict

    public interface CacheRepository extends CrudRepository<T, String> {
    
        @Cacheable("cacheName")
        T findOne(String name);
    
        @Cacheable("cacheName")
        @CacheEvict(value = "cacheName", allEntries = true)
        Iterable<T> findAll();
    
        @Override
        @CachePut("cacheName")
        T save(T entity);
    
        @Override
        @CacheEvict("cacheName")
        void delete(String name);
    }
    

Reference



回答3:

I solved the this in the following way and its working fine


public interface BookRepositoryCustom {

    Book findOne(Long id);

}

public class BookRepositoryImpl extends SimpleJpaRepository<Book,Long> implements BookRepositoryCustom {

    @Inject
    public BookRepositoryImpl(EntityManager entityManager) {
        super(Book.class, entityManager);
    }

    @Cacheable(value = "books", key = "#id")
    public Book findOne(Long id) {
        return super.findOne(id);
    }

}

public interface BookRepository extends JpaRepository<Book,Long>, BookRepositoryCustom {

}


回答4:

Try provide MyCRUDRepository (an interface and an implementation) as explained here: Adding custom behaviour to all repositories. Then you can override and add annotations for these methods:

findOne(ID id)
delete(T entity)
delete(Iterable<? extends T> entities)
deleteAll() 
delete(ID id)