【问题标题】:Object aggregations in Querydsl-jpaQuerydsl-jpa 中的对象聚合
【发布时间】:2021-07-11 07:38:42
【问题描述】:

我想问一下是否有可能在 JPA(使用 HQL)中使用对象聚合函数。 json_agg()等函数

我想实现类似的目标。所以目标是获取实体并将其转换为字符串。

Expressions.stringTemplate("jsonb_agg(json_build_object('entity', {0}))", qEntity.id)

为什么我尝试这样做我收到org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode 错误。我读过这个问题是我不能使用 HQL,因为我不能在 json 聚合函数中使用 HQL 对象属性。

我想尽可能避免使用 querydsl-sql(它使 docker 应用程序部署变得复杂,它需要连接到数据库等)。 那么有什么方法可以使用 HQL 来聚合这样的对象吗?我正在使用 spring-data-jpa,所以如果有更好的解决方案,这是使用这个工具的机会。

【问题讨论】:

    标签: sql spring spring-data hql querydsl


    【解决方案1】:

    您的 QueryDSL sn-p 看起来不错,但您需要为 JSONB_AGGJSON_BUILD_OBJECT 注册自定义函数以及 JSONB 结果的自定义类型。

    对于自定义 JSONB 类型,您可以使用 hibernate-types 库中的 JsonBinaryType

    对于自定义函数,您需要创建一个MetadataBuilderInitializer ,将 SQL 函数注册到 Hibernate。您可以从我的 hibernate-types-querydsl-apt 库中获取灵感(例如 ArrayFunctionInitializer)。专门应用于 JSON 函数,您最终会得到以下内容:

    public class ArrayFunctionInitializer implements MetadataBuilderInitializer {
    
        @Override
        public void contribute(MetadataBuilder metadataBuilder, StandardServiceRegistry standardServiceRegistry) {
            metadataBuilder.applySqlFunction("json_build_object", new StandardSQLFunction("json_build_object", JsonBinaryType.INSTANCE));
            metadataBuilder.applySqlFunction("jsonb_agg", new StandardSQLFunction("jsonb_agg", JsonBinaryType.INSTANCE));
        }
    }
    

    【讨论】:

    • 您好,感谢您的回答。我读过那篇休眠类型文章,在我看来,我可以将 json 存储为列。这不是我真正想要的。我想使用我现在拥有的结构(所以 qEntity 已经链接了一些其他实体)并且只使用 group by 并且因此能够选择整个实体(如果可能的话)或者至少使用选择的 qClass 字段创建 json。另外,我真的不明白如何使用 Querydsl-jpa 在我的 Spring MVC 代码中使用该 Initializer。
    • 在向 Hibernate 注册自定义 SQL 函数时,您需要提供该博文中描述的类型类作为返回类型的参数。为了向 Hibernate 注册 MetadataContributor,您必须创建一个服务提供者文件。
    猜你喜欢
    • 1970-01-01
    • 2019-05-31
    • 1970-01-01
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多