如何查询实体中版本最大的指定行?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
相关产品推荐
相关产品推荐

