Quarkus Panache Reactive单列查询project投影失效问题咨询
问题原因
project()方法的实现逻辑是自动在查询语句前拼接SELECT new 投影类全限定名(字段列表)前缀,仅适用于不手写select子句的场景。你自己手写了带select的聚合查询语句,再调用project()就会把两段select逻辑拼在一起,最终生成重复select的错误SQL。另外你代码里的参数类名拼写有误,正确类名是Parameters,不是Paramater,这个拼写问题也会触发运行错误。
可行解决方案
根据你的查询场景,选下面任意一种写法即可:
- 单聚合值直接查询(最简洁,适配你的sum场景)
你只需要获取sum计算出的单个数值,不需要额外定义Result投影类,直接用对应数值类型接收结果即可:
@ApplicationScoped class TestRepository: PanacheRepository<Test> { fun getSum(name: String): Double? = find("select sum(l.amount) from Test l where l.name = :name", Parameters().with("name", name) ).singleResult() }
- 自定义投影类适配多字段/聚合结果
如果确实需要用自定义类接收结果,直接在HQL中手写全限定名的构造器表达式,不要调用project()方法,注意构造器内参数顺序、类型必须和投影类构造参数完全匹配:
// 替换org.example为你Result类的实际包路径 @ApplicationScoped class TestRepository: PanacheRepository<Test> { fun getSum(name: String) = find("select new org.example.Result(sum(l.amount)) from Test l where l.name = :name", Parameters().with("name", name) ).singleResult() }
- 普通表字段投影用project()的正确姿势
如果是查询实体本身存在的普通字段(非聚合、非计算字段),不要手写select子句,只传查询条件,让Panache自动生成投影select逻辑:
// 示例:按name查询,投影为仅含amount字段的Result fun getAmountByName(name: String) = find("name = :name", Parameters().with("name", name)) .project(Result::class) .singleResult()
注意:只要你手写了以
select开头的完整HQL语句,就不要调用project()方法,否则必然出现select子句重复拼接的问题。
内容的提问来源于stack exchange,提问作者dondragon2
相关产品推荐
相关产品推荐

