当前位置: 首页 > 知识库问答 >
问题:

Spring缓存驱逐不起作用

訾渝
2023-03-14

嗨,我在执行方法时遇到清理缓存的问题。这是我的配置和缓存方法:

@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;
    }
}

我要缓存的这个方法:

@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);
    }

在执行此方法时,我希望按类型清理缓存:

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

新闻消息对象看起来像:

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

    <other fileds>

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

缓存工作正常,第一次查询DB时,第二次从缓存中提取数据。问题是当我更新数据时,@CacheEvict不会清理缓存。我试图使用以下注释清理所有缓存:@cacheexit(cacheNames={CacheConfiguration.RSS\u NEWS\u BY\u TYPE\u cache},allEntries=true),但它也不起作用。你能帮我吗?

共有3个答案

仇迪
2023-03-14

您的NewsMessage类中需要一个公共RssType getType()方法。@CacheEvict注释中的关键表达式“#news.type”需要一个名为“type”的公共字段或一个名为“getType”的公共getter方法。

钱承允
2023-03-14

我找到了解决问题的方法。我不得不将注释移到spring数据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);
}

现在它像我预期的那样工作,但仍然不知道为什么它在我的服务中不工作。也许是因为我的服务实现了两个接口?

@Service
public class NewsMessageService implements RssObserver, NewsMessageServiceable {
}
逄宁
2023-03-14

从哪里调用save()方法?

在您自己的回答中,您似乎已将注释移动到另一个类/接口以调用该类/接口的代理对象(顺便说一句,注释通常不应在接口中使用,因为它们通常不会被默认配置捕获)。

因此我的问题是:你知道spring aop代理吗?您必须从类之外的方法调用带注释的方法来调用代理对象。

一般留档在这里:http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#aop-understanding-aop-proxies

或者用这里的例子http://spring.io/blog/2012/05/23/transactions-caching-and-aop-understanding-proxy-usage-in-spring

 类似资料:
  • 我使用Spring缓存抽象,定义了多个缓存。有时,当数据更改时,我想逐出多个缓存。是否可以使用Spring的CacheExit注释逐出多个缓存?

  • 在我的项目中,我使用了一个@Cacheable注释ia一个服务方法,它返回涉及书籍和一些标记的计算结果,我想在一个@Controller类方法中退出缓存,该方法将一本新书添加到数据库中,因为这本新书将是新计算所必需的。 服务类:@Cacheable("metas") 控制器类:@RequestMapping@CacheEvict(value=“metas”,allEntries=true)

  • 问题内容: 我正在尝试但未能成功在具有以下 依赖项的* Spring Data 和 Hibernate environmet中缓存查询: * 我的实体服务的Spring Data Repository(ServiceRepository)是 从中调用存储库的@Cacheable方法 我的缓存配置文件(jpa-context.xml)是 它的灵感来自spring-data-jpa-examples

  • 我使用Spring Boot 1.4.1和spring-boot-starter-data-jpa 当查询我的自定义方法时,比如'find byname(String name)',它不是缓存。

  • 给出了一个带有express的nodejs应用程序,它通过nginx运行。我正在尝试使用ETag添加缓存支持。 如果没有nginx,如果应用程序被直接调用它的工作。我设置了如果无匹配头,并收到一个304。 对于nginx,响应总是200。 我的Nginx配置: 快车的日志记录。 信息:HTTP GET/app/statusCode=200,url=/app/,connection=upgrade,

  • 我在Springboot中开发了一个RESTendpoint,它接受ID,并用进行响应。此endpoint用注释标记。现在有两件事可以发生在给定的终点。 情况1:请求ID存在于DB中,并产生一个需要进行重定向的URL。在这种情况下,应该缓存响应,以便在相同ID的连续请求时,可以从缓存提供结果 情况2:请求的ID在DB中不存在,因此重定向应该发生在特定的URL,在此场景中不应该进行缓存。 如果我从这