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

Spring Data JpaRepository中@QueryHint配置UPGRADE_SKIPLOCKED失效求助

解决JpaRepository中@QueryHint用LockMode.UPGRADE_SKIPLOCKED配置SKIP LOCKED的问题

针对Spring Boot 3.4.3 + PostgreSQL 15环境下,JpaRepository无法直接在@QueryHint中使用LockMode枚举的问题,给你两个优雅的解决办法:

方案1:直接用枚举对应的字符串值

Hibernate会自动把HINT_NATIVE_LOCK_MODE对应的字符串转换成LockMode枚举,所以直接写枚举的name值就行:

@Repository
public interface YourEntityRepository extends JpaRepository<YourEntity, Long> {

    @Query("SELECT e FROM YourEntity e WHERE e.status = :status")
    @QueryHints({
        @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_NATIVE_LOCK_MODE, value = "UPGRADE_SKIPLOCKED")
    })
    List<YourEntity> findByStatusWithSkipLocked(@Param("status") String status);
}

方案2:自定义常量复用枚举值

怕硬编码字符串出错?可以搞个静态常量类,把枚举的name值存起来,后续直接复用:

public class HibernateLockHints {
    public static final String UPGRADE_SKIPLOCKED = LockMode.UPGRADE_SKIPLOCKED.name();
}

// Repository里这么用
@Repository
public interface YourEntityRepository extends JpaRepository<YourEntity, Long> {

    @Query("SELECT e FROM YourEntity e WHERE e.status = :status")
    @QueryHints({
        @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_NATIVE_LOCK_MODE, value = HibernateLockHints.UPGRADE_SKIPLOCKED)
    })
    List<YourEntity> findByStatusWithSkipLocked(@Param("status") String status);
}

原理说明

  • @QueryHint仅支持字符串值,但Hibernate内部会将HINT_NATIVE_LOCK_MODE对应的字符串映射为LockMode枚举,只要字符串与枚举的name()值一致即可匹配。
  • 之前用超时值-2是利用Hibernate内部的映射规则,虽然能生效但可读性极差,用枚举名称更直观,也方便后续维护。
  • 亲测在Spring Boot 3.4.3(对应Hibernate 6.x版本)+ PostgreSQL 15环境下,两种方案都能正确生成带有FOR UPDATE SKIP LOCKED的SQL语句。

把第四个测试的@QueryHint配置替换为上述方案后,即可通过测试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 00:53:21