简体   繁体   中英

Spring Cache Evict does not work

Hi I have problem with clean cache when method is executed. Here is my configuration and caches methods:

@Configuration
@EnableCaching
@AutoConfigureAfter(value = {MetricsConfiguration.class, DatabaseConfiguration.class})
@Profile("!" + Constants.SPRING_PROFILE_FAST)
public class CacheConfiguration {

    private final Logger log = LoggerFactory.getLogger(CacheConfiguration.class);
    public static final String STOCK_DETAILS_BY_TICKER_CACHE = "stockDetailsByTickerCache";
    public static final String RSS_NEWS_BY_TYPE_CACHE = "rssNewsByTypeCache";

    @Bean
    public CacheManager cacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        List<Cache> caches = new ArrayList<Cache>();
        caches.add(new ConcurrentMapCache(STOCK_DETAILS_BY_TICKER_CACHE));
        caches.add(new ConcurrentMapCache(RSS_NEWS_BY_TYPE_CACHE));
        cacheManager.setCaches(caches);
        return cacheManager;
    }
}

This method i want to cache:

@Cacheable(cacheNames = CacheConfiguration.RSS_NEWS_BY_TYPE_CACHE, key = "#type")
    public ResponseEntity<List<NewsDetailsDTO>> getLatestNewsMessageByType(RssType type) {
        Pageable pageable = new PageRequest(0, 5, Sort.Direction.DESC, "createdDate");
        List<NewsMessage> latestNewsMessage = newsMessageRepository.findByType(type, pageable).getContent();
        return new ResponseEntity<List<NewsDetailsDTO>>(mapToDTO(latestNewsMessage), HttpStatus.OK);
    }

On execution of this method i would like to clean cache by type:

@CacheEvict(cacheNames={CacheConfiguration.RSS_NEWS_BY_TYPE_CACHE}, beforeInvocation = true, key = "#news.type")
    public void save(NewsMessage news) {
        newsMessageRepository.save(news);
    }

And NewsMessage object looks like:

@Entity
@Table(name = "NEWS_MESSAGE")
public class NewsMessage extends ChatMessage {

    <other fileds>

    @NotNull
    @Enumerated(EnumType.STRING)
    private RssType type;
}

The cache thing works fine, by the first time there is a query to DB by second and next the data is fetch from cache. Problem is when I update data the @CacheEvict does not clean the cache. I was trying to clean all cache using this annotation: @CacheEvict(cacheNames={CacheConfiguration.RSS_NEWS_BY_TYPE_CACHE}, allEntries = true) But it also does not work. Could you help me?

From where do you call the save() method?

In your own answer it looks like you have moved the annotations to another class/interface to invoke the proxy object of that class/interface (btw annotations should generally not be used in interfaces, because they often don't get catched with default configuration).

Therefore my question: do you know the spring aop proxy? You have to call annotated methods from methods outside your MessageRepository class to invoke the proxy object.

General documentation for that is here: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#aop-understanding-aop-proxies

or with examples here http://spring.io/blog/2012/05/23/transactions-caching-and-aop-understanding-proxy-usage-in-spring

You need a public RssType getType() method in your NewsMessage class. The key expression "#news.type" in your @CacheEvict annotation is expecting either a public field named "type" or a public getter method named "getType".

I found the workaround for my problem. I had to moved the annotation upper to the spring data jpa interace.

public interface NewsMessageRepository extends JpaRepository<NewsMessage, Long> {

    @CacheEvict(cacheNames = {CacheConfiguration.RSS_NEWS_BY_TYPE_CACHE}, beforeInvocation = true, key = "#p0.type")
    NewsMessage save(NewsMessage news);
}

Now it is working as i expected, but still have no idea why it did not work in my service. Maybe because my services implements two interfaces?

@Service
public class NewsMessageService implements RssObserver, NewsMessageServiceable {
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM