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

Spring JPA非原生查询实现分组返回值列表的问题

解决JPQL中ARRAY_AGG报错的方案

方案一:使用Hibernate原生collect聚合函数

Hibernate的JPQL原生支持collect函数,专门用来将分组后的元素收集为集合,完全适配JPQL语法规则,替换掉ARRAY_AGG即可解决问题。

操作步骤:

  • 修改Repository中的JPQL查询语句:
@Query("SELECT new MyProjection(a.key, collect(a.value)) FROM A a WHERE a.key IN (:keys) GROUP BY a.key")
List<MyProjection> findGroupedValuesByKeys(@Param("keys") Collection<String> keys);
  • 确保MyProjection的构造函数接受集合类型参数:
public class MyProjection {
    private String key;
    private List<UUID> values;

    public MyProjection(String key, List<UUID> values) {
        this.key = key;
        this.values = values;
    }

    // getter/setter方法
}

方案二:自定义注册ARRAY_AGG函数

如果业务必须使用数组类型而非集合,可以通过自定义Hibernate SQL函数的方式,让JPQL正确识别ARRAY_AGG。

操作步骤:

  1. 创建自定义函数注册器:
public class CustomSqlFunctionInitializer implements MetadataBuilderInitializer {
    @Override
    public void contribute(MetadataBuilder metadataBuilder, StandardServiceRegistry serviceRegistry) {
        // 注册ARRAY_AGG为支持UUID数组的聚合函数
        metadataBuilder.applySqlFunction(
            "array_agg",
            new StandardSQLFunction(
                "array_agg",
                UUIDArrayType.INSTANCE
            )
        );
    }
}
  1. 在配置文件中指定注册器路径:
# application.properties
spring.jpa.properties.hibernate.metadata_builder_initializer=com.yourpackage.CustomSqlFunctionInitializer
  1. 此时原JPQL语句可正常使用,同时确保MyProjection的构造函数接受UUID[]类型参数:
public MyProjection(String key, UUID[] values) {
    this.key = key;
    this.values = values;
}

报错原因说明

原生SQL(如PostgreSQL)中的ARRAY_AGG属于普通聚合函数,但Hibernate的JPQL解析器将其归类为有序集合聚合函数,这类函数强制要求搭配WITHIN GROUP或OVER子句,因此直接使用会抛出语义异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 03:22:38