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

如何让Hibernate二级缓存识别实体自定义命名的ID字段?

解决Hibernate 6中自定义ID字段查询的缓存生效问题

Hibernate的二级缓存对findById()这类原生ID查询会自动触发,但自定义的findByDisplayId()方法即使查询的是ID字段,默认不会被识别为ID查询,因此无法命中缓存。以下是几种可行的解决方式:

方式一:使用Spring缓存注解绑定缓存

在Repository的自定义方法上添加Spring的@Cacheable注解,指定对应缓存区域和缓存key,让Spring缓存抽象拦截方法调用并复用缓存:

import org.springframework.cache.annotation.Cacheable;

public interface DisplayRepository extends JpaRepository<Display, Long> {

    @Cacheable(value = "display-cache", key = "#displayId")
    Optional<Display> findByDisplayId(Long displayId);

}

注意:需要在Spring Boot主类上添加@EnableCaching开启缓存功能,同时确保缓存管理器配置与Hibernate的Ehcache设置一致。

方式二:通过Hibernate查询缓存注解标记

使用自定义HQL查询,并添加Hibernate的@QueryCache注解,让Hibernate识别该查询并关联实体缓存:

import org.hibernate.annotations.QueryCache;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface DisplayRepository extends JpaRepository<Display, Long> {

    @Query("SELECT d FROM Display d WHERE d.displayId = :displayId")
    @QueryCache(region = "display-cache")
    Optional<Display> findByDisplayId(@Param("displayId") Long displayId);

}

此方式会让Hibernate优先从实体二级缓存中获取数据,同时也可缓存查询结果本身。

方式三:直接使用EntityManager的find方法

在业务代码中注入EntityManager,调用其find()方法,该方法与findById()逻辑一致,会自动触发Hibernate二级缓存:

import jakarta.persistence.EntityManager;
import org.springframework.beans.factory.annotation.Autowired;

// 业务类中
@Autowired
private EntityManager entityManager;

public Display getDisplayById(Long id) {
    return entityManager.find(Display.class, id);
}

额外检查项

  • 确认实体类上的@Cache注解配置正确,region与Ehcache配置文件中的缓存区域名称匹配
  • 验证Ehcache配置文件中已定义display-cache区域,且缓存策略(如过期时间)符合需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 10:07:04