我正在使用JPQL并希望在Constructor Expression中接收一些常规参数和集合以直接创建DTO对象。但是如果Collection是空的,我总是会收到一个错误,因为他找不到合适的构造函数:
DTO-Class看起来如下:
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;
}
现在,Constructor Expression看起来如下:
return (List<DTO>) getEm().createQuery("SELECT DISTINCT NEW de.DTO(p.id, p.name, p.childs)
FROM Parent p").getResultList();
目前的问题是,如果Collection p.childs为空,它表示它找不到正确的构造函数,它需要(long,String,Child)而不是(long,String,Collection)。
您有任何解决方案,或者根本无法在构造函数表达式中使用Collection?
哦,还有一件事:如果我轻松创建两个构造函数(...,Collection childs AND ...,Child childs)我没有得到任何结果,但也没有错误......在我看来并不是很满意: - /
这不是答案。
据我所知,JPA 2.0规范不允许在构造函数表达式中使用集合作为参数。 4.8节定义了一个这样的构造函数表达式:
constructor_expression ::=
NEW constructor_name ( constructor_item {, constructor_item}* )
constructor_item ::=
single_valued_path_expression |
scalar_expression |
aggregate_expression |
identification_variable
一个 single_valued_path_expression
它听起来像是一个属性表达式,指向某种标量(例如 p.id
), 一个 scalar_expression
也是指向标量的表达式,a aggregate_expression
是一个像函数的应用程序 sum
它将多值表达式减少为标量值,并且 identification_variable
是您查询的类型的引用。这些都不是收藏价值的。假设我已经阅读了规范。
因此,如果您的JPA提供程序允许您在构造函数表达式中使用集合值参数,那是因为它超出了规范。这是非常好的,但不是你必须依赖的东西!
尝试,
public DTO (long id, String name, Object children)
我遇到了类似的问题,并在James建议的DTO构造函数中尝试了“Object”,但是传入了一个子对象,它似乎只是第一个子节点,而不是预期的子节点List / Array。
我最终得到一个“正常”查询,在for循环中创建所有DTO。
TypedQuery<Parent> query = em.createQuery("SELECT p FROM Parent p", Parent class);
List<Parent> list = query.getResultList();
List<DTO> result = new ArrayList<>();
for (Parent p : list)
{
DTO dto = new DTO();
//set dto props and fill collection
result.add(obj);
}
return result;