Как я могу @CachePut для сбора весной?

#java #spring #spring-boot #caching #ehcache

#java #весна #весенняя загрузка #кэширование #ehcache

Вопрос:

Для кэширования я использую Ehcache3 в качестве поставщика. Допустим, у меня есть эти методы:

 @Transactional
@Cacheable(cacheNames = "findAllPosts")
public Page<Post> getAllPosts(Pageable pageable) {
    return postRepository.findAll(pageable);
}

@Transactional
@Cacheable(cacheNames = "findPostById")
public Post findById(Long id) {
    return postRepository.findById(id).orElseThrow(exceptionHelper.getEntityNotFoundException(id, Post.class));
}

@Transactional
@CachePut(cacheNames = "findPostById", key = "#result.id")
public Post update(Long postId, Post postToUpdate) {
    Post post = postRepository.getOne(postId);
    post.setTitle(postToUpdate.getTitle());
    post.setContent(postToUpdate.getContent());
    post.setUpdated(LocalDateTime.now());
    return post;
}
 

Я хочу, конечно, кэшировать эти методы. Это работает, но @CachePut влияет только findPostById и не влияет findAllPosts , даже если я добавляю findAllPosts в cacheNames. Когда я обновляю сообщение, оно отображается для одного сообщения (по идентификатору), а не для getAllPosts (кэш не обновляется для этого метода). Что я могу сделать, чтобы обновить не только отдельный объект, но и всю коллекцию? Есть ли что-то подобное @CollectionCache ?

Комментарии:

1. Вы уверены, что это не потому, что вы используете ‘key’ в своем методе @CachePut, но не используете ключ в своих findAllPosts() и findPostById() ?

Ответ №1:

Одним из решений для этого было бы удаление кэша для списка всякий раз, когда обновляется один элемент.

Вам нужно будет автоматически подключить CacheManager, получить доступ к кешу оттуда и удалить то, что вам нужно, вручную в методе обновления.

Пример кода:

 @Autowired 
private CacheManager cacheManager;

@Transactional
@CachePut(cacheNames = "findPostById", key = "#result.id")
public Post update(Long postId, Post postToUpdate) {

    Cache allPostsCache = cacheManager.getCache("cacheName").evict("cacheKey");

    Post post = postRepository.getOne(postId);
    post.setTitle(postToUpdate.getTitle());
    post.setContent(postToUpdate.getContent());
    post.setUpdated(LocalDateTime.now());
    return post;
}
 

Конечно, вам нужно заменить «cacheName» и «CacheKey» своими значениями.