JPQL:在构造函数表达式中接收集合

2022-09-02 13:10:35

我正在使用JPQL,并希望在构造函数表达式中接收一些普通参数和集合,以直接创建DTO对象。但是如果集合是空的,我总是收到一个错误,因为他没有找到正确的构造函数:

DTO 类如下所示:

public class DTO {
    private long id;
    private String name;
    private Collection<Child> children;

    public DTO (long id, String name, Collection<Child> children){
    this.id = id;
    this.name = name;
    this.children= children;
    }
}

儿童班:

public class Child {
    private String name;
    private int age;
}

现在构造函数表达式如下所示:

return (List<DTO>) getEm().createQuery("SELECT DISTINCT NEW de.DTO(p.id, p.name, p.childs) 
                                          FROM Parent p").getResultList();

目前的问题是,如果集合 p.childs 为空,它说它没有找到正确的构造函数,它需要(long,String,Child)而不是(long,String,Collection)。

您是否有任何解决方案,或者根本无法在构造函数表达式中使用集合?

哦,还有一件事:如果我很容易地创建两个构造函数(...,集合子项和...,子项),我没有得到任何结果,但也没有错误......在我眼里不是很满意:-/


答案 1

JPA 规范(至少版本 2.0、2.1 和 2.2)不允许在构造函数表达式中使用集合作为参数。第 4.8 节定义了一个构造函数表达式,如下所示:

constructor_expression ::=
        NEW constructor_name ( constructor_item {, constructor_item}* )
constructor_item ::=
        single_valued_path_expression |
        scalar_expression |
        aggregate_expression |
        identification_variable

A 是它听起来的样子 - 指向某种类型的标量的属性表达式(例如 ),a 也是指向标量的表达式,a 是函数的应用,例如将多值表达式简化为标量表达式,并且 a 是对要查询的类型的引用。这些都不能进行集合值。single_valued_path_expressionp.idscalar_expressionaggregate_expressionsumidentification_variable

因此,如果您的 JPA 提供程序允许您在构造函数表达式中使用集合值参数,那是因为它超出了规范。这很好,但不是你一定可以依赖的东西!


答案 2

尝试

public DTO (long id, String name, Object children)