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(); }
补充说明
- 你的
application.properties中已开启查询缓存(spring.jpa.properties.hibernate.cache.use_query_cache=true),这是查询缓存生效的前提,无需修改。 - 查询缓存与二级缓存配合工作:第一次执行
findRegionsByExternalid时,Hibernate会执行JDBC查询,同时将查询结果(实体主键)存入查询缓存,实体数据存入二级缓存;后续调用时,先从查询缓存拿到主键,再从二级缓存读取实体,不会再执行JDBC语句。 - 实体类使用的
READ_ONLY缓存策略,适合数据不常变更的场景,能保证缓存一致性。
内容的提问来源于stack exchange,提问作者danilakds
相关产品推荐
相关产品推荐

