You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate二级缓存结合JPA使用问题:自定义方法不命中缓存

问题分析

你的配置已正确开启Hibernate二级缓存和查询缓存,实体类也标记了可缓存,但自定义的findRegionsByExternalid方法未命中缓存的核心原因是:

  • findById是基于主键的查询,Hibernate二级缓存(实体缓存)本身按实体主键存储数据,因此直接从缓存读取,无需额外配置。
  • 自定义的findRegionsByExternalid属于非主键派生查询,这类查询的结果不会自动关联二级缓存,必须显式开启查询缓存来缓存「查询条件与实体主键的映射关系」,后续调用时才能先通过查询缓存拿到主键,再从二级缓存获取实体数据,避免执行JDBC语句。
解决方案

给自定义的findRegionsByExternalid方法添加@QueryHints注解,标记该查询可缓存,让Hibernate将查询结果存入查询缓存。

修改后的JpaRepository代码
public interface RegionsRepo extends JpaRepository<Regions, Long> {
    
    @QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
    Optional<Regions> findRegionsByExternalid(Integer id);

    @Override
    Optional<Regions> findById(Long aLong);

    @Override
    @QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
    List<Regions> findAll();
}
补充说明
  1. 你的application.properties中已开启查询缓存(spring.jpa.properties.hibernate.cache.use_query_cache=true),这是查询缓存生效的前提,无需修改。
  2. 查询缓存与二级缓存配合工作:第一次执行findRegionsByExternalid时,Hibernate会执行JDBC查询,同时将查询结果(实体主键)存入查询缓存,实体数据存入二级缓存;后续调用时,先从查询缓存拿到主键,再从二级缓存读取实体,不会再执行JDBC语句。
  3. 实体类使用的READ_ONLY缓存策略,适合数据不常变更的场景,能保证缓存一致性。

内容的提问来源于stack exchange,提问作者danilakds

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 20:20:13