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

如何查询实体中版本最大的指定行?HQL查询报错求助

问题修正方案

错误原因

原HQL的having子句存在语法错误,having必须配合完整的条件表达式(如max(t.version) = t.version),但即便修正语法,这种写法也无法正确返回目标实体记录——因为group by t.id后,HQL无法直接返回整行实体数据。

修正方案

方案一:子查询关联(兼容多数JPA版本)

先通过子查询获取每个AssessmentTemplate.id对应的最大version,再关联主查询筛选符合条件的完整记录:

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;

// ...

@Query("SELECT t FROM AssessmentTemplate t " +
       "WHERE t.riskLabel.name = :name " +
       "AND (t.id, t.version) IN (" +
       "    SELECT at.id, MAX(at.version) FROM AssessmentTemplate at " +
       "    WHERE at.riskLabel.name = :name " +
       "    GROUP BY at.id" +
       ")")
List<AssessmentTemplate> getVersion(@Param("name") String name);
  • 注意:用@Param注解绑定JPA查询参数,替换原代码中的@RequestParam(@RequestParam是Spring MVC的参数绑定注解,不适用于JPA查询)。

方案二:窗口函数(Hibernate 5.2+ 支持)

利用ROW_NUMBER()窗口函数按id分组、version降序排序,直接取每组的第一条记录(即对应最大version的记录):

@Query("SELECT t FROM (" +
       "    SELECT at, ROW_NUMBER() OVER (PARTITION BY at.id ORDER BY at.version DESC) rn " +
       "    FROM AssessmentTemplate at " +
       "    WHERE at.riskLabel.name = :name" +
       ") t WHERE t.rn = 1")
List<AssessmentTemplate> getVersion(@Param("name") String name);
  • 优势:语法更简洁,无需重复编写筛选条件。

额外注意事项

  • 原查询中的distinct关键字可移除,因为最终结果每个id仅对应一条最大version的记录,不会出现重复。
  • 确保riskLabel关联关系映射正确,避免因懒加载导致的查询异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 10:33:19