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

Spring Boot 3.x迁移后JPA Repository查询验证失败求助

迁移Spring Boot 3.x后JPA查询创建失败问题解决

问题现象

将项目迁移至Spring Boot 3.1.4(Spring Boot 3.2搭配Hibernate 6.4时问题复现)后,IndemniteRepository中的findAllForExport方法无法创建查询,报错提示查询验证失败。

核心错误日志

Could not create query for public abstract java.util.List com.xx.xx.xx.repository.IndemniteRepository.findAllForExport(com.xx.xx.xx.domain.penalite.AvisPenaliteStatutEnum,java.math.BigDecimal,java.util.List); 

Reason: Validation failed for query for method public abstract java.util.List com.xx.xx.xx.repository.IndemniteRepository.findAllForExport(com.xx.xx.xx.domain.penalite.AvisPenaliteStatutEnum,java.math.BigDecimal,java.util.List)

Hibernate解析错误

Caused by: org.hibernate.query.sqm.ParsingException line 1:241 no viable alternative at input 'SELECTindFROMIndemniteindWHEREind.indemniteAFacturer>:indemniteAFacturerANDind.avis.statut=:statutAND(:statut!=com.xx.xx.xx.domain.penalite.AvisPenaliteStatutEnum.POUR_FACTUREANDind.avis.facturationEnAttenteISTRUE'

相关Repository代码

@Repository
public interface IndemniteRepository extends JpaRepository<Indemnite, Long>, JpaSpecificationExecutor<Indemnite> {

    @Query("SELECT ind FROM Indemnite ind " +
            "WHERE ind.indemniteAFacturer > :indemniteAFacturer " +
            "AND ind.avis.statut = :statut " +
            "AND (:statut != com.xx.xx.xx.domain.penalite.AvisPenaliteStatutEnum.POUR_FACTURE AND ind.avis.facturationEnAttente IS TRUE OR ind.avis.facturationEnAttente IS FALSE) " +
            "AND ind.avis.typePenalite.name IN :typePenalite " +
            "ORDER BY ind.avis.date ASC")
    List<Indemnite> findAllForExport(@Param("statut") AvisPenaliteStatutEnum statut,
                                     @Param("indemniteAFacturer") BigDecimal indemniteAFacturer,
                                     @Param("typePenalite") List<TypePenaliteEnum> typePenalite);
}

问题原因

Hibernate 6.x对JPQL的解析规则比旧版本更严格:

  1. 直接在JPQL中引用Java枚举全限定类名的写法不再被支持
  2. 原查询中的逻辑表达式未明确优先级,进一步触发解析失败

解决方案

1. 修正枚举引用方式

在Spring Data JPA的@Query中,需通过SpEL表达式引用Java枚举常量,格式为:#{T(全限定类名).枚举值},替换原直接引用枚举类的写法。

2. 明确逻辑表达式优先级

调整括号包裹范围,避免AND/OR优先级导致的逻辑歧义。

修改后的查询代码

@Repository
public interface IndemniteRepository extends JpaRepository<Indemnite, Long>, JpaSpecificationExecutor<Indemnite> {

    @Query("SELECT ind FROM Indemnite ind " +
            "WHERE ind.indemniteAFacturer > :indemniteAFacturer " +
            "AND ind.avis.statut = :statut " +
            "AND ((:statut != #{T(com.xx.xx.xx.domain.penalite.AvisPenaliteStatutEnum).POUR_FACTURE} AND ind.avis.facturationEnAttente IS TRUE) OR ind.avis.facturationEnAttente IS FALSE) " +
            "AND ind.avis.typePenalite.name IN :typePenalite " +
            "ORDER BY ind.avis.date ASC")
    List<Indemnite> findAllForExport(@Param("statut") AvisPenaliteStatutEnum statut,
                                     @Param("indemniteAFacturer") BigDecimal indemniteAFacturer,
                                     @Param("typePenalite") List<TypePenaliteEnum> typePenalite);
}

替代方案:使用枚举字符串值

若不想使用SpEL,可直接使用枚举的字符串值进行比较(需保证枚举name()值与数据库存储值一致):

@Query("SELECT ind FROM Indemnite ind " +
        // ... 其他条件
        "AND ((:statut != 'POUR_FACTURE' AND ind.avis.facturationEnAttente IS TRUE) OR ind.avis.facturationEnAttente IS FALSE) " +
        // ... 其他条件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 11:22:08