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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 18:24:35