尝试将JPA @ElementCollection的内容读入值对象时出现异常。
标准代码(我不使用预生成的元模型):
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<KursplanListDTO> cq = cb.createQuery(KursplanListDTO.class);
Metamodel m = em.getMetamodel();
EntityType<Kursplan> Kursplan_ = m.entity(Kursplan.class);
EntityType<Institution> Institution_ = m.entity(Institution.class);
Root<Kursplan> kursplan = cq.from(Kursplan.class);
cq.multiselect(kursplan.get("id"), kursplan.get("name"), kursplan.get("institution"), kursplan.get("participants"));
TypedQuery<KursplanListDTO> tq = em.createQuery(cq);
List<KursplanListDTO> result = tq.getResultList();
实体(&#39; Kursplan&#39;):
...
@NotNull
private String name;
@NotNull
@ManyToOne(fetch = FetchType.EAGER)
private Institution institution
@ElementCollection(targetClass = String.class, fetch = FetchType.EAGER)
@Column(name = "participants")
private List<String> participants = new ArrayList<>();
...
DTO(KursplanListDTO):
...
public KursplanListDTO(Long id, String name, Institution institution, List<String> participants) {
...
}
...
当我运行以上内容时,我得到了例外: java.lang.IllegalArgumentException:org.hibernate.hql.internal.ast.QuerySyntaxException:无法在类[se.testapp.business.kursplan.entity.KursplanListDTO]上找到适当的构造函数。预期的参数是:long,java.lang.String,se.testapp.business.systemdata.entity.Institution,java.util.Collection
如果我在DTO构造函数中将List更改为java.util.Collection,我会得到此异常(来自日志):
12:07:22,056 INFO [stdout] (default task-2) Hibernate:
12:07:22,056 INFO [stdout] (default task-2) /* select
12:07:22,057 INFO [stdout] (default task-2) new se.testapp.business.kursplan.entity.KursplanListDTO(generatedAlias0.id,
12:07:22,057 INFO [stdout] (default task-2) generatedAlias0.name,
12:07:22,057 INFO [stdout] (default task-2) generatedAlias0.institution,
12:07:22,057 INFO [stdout] (default task-2) generatedAlias0.participants)
12:07:22,057 INFO [stdout] (default task-2) from
12:07:22,057 INFO [stdout] (default task-2) Kursplan as generatedAlias0 */ select
12:07:22,058 INFO [stdout] (default task-2) kursplan0_.id as col_0_0_,
12:07:22,058 INFO [stdout] (default task-2) kursplan0_.name as col_1_0_,
12:07:22,061 INFO [stdout] (default task-2) kursplan0_.institution_id as col_2_0_,
12:07:22,061 INFO [stdout] (default task-2) . as col_3_0_
12:07:22,061 INFO [stdout] (default task-2) from
12:07:22,061 INFO [stdout] (default task-2) Kursplan kursplan0_
12:07:22,061 INFO [stdout] (default task-2) inner join
12:07:22,061 INFO [stdout] (default task-2) Institution institutio1_
12:07:22,061 INFO [stdout] (default task-2) on kursplan0_.institution_id=institutio1_.id
12:07:22,061 INFO [stdout] (default task-2) inner join
12:07:22,061 INFO [stdout] (default task-2) Kursplan_participants participants2_
12:07:22,061 INFO [stdout] (default task-2) on kursplan0_.id=participants2_.Kursplan_id
12:07:22,064 WARN [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-2) SQL Error: 156, SQLState: S0001
12:07:22,065 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-2) Incorrect syntax near the keyword 'as'.
显然&#39;。&#39;在col_3_0_看起来不正确。
如果我遗漏了&#39;参与者&#39;,它们都可以使用多选和DTO构造函数(其他数据会按原样读入DTO)。
那么我可以做什么来制作标准让我把elementcollection的内容放到一个值对象中(在我的例子中是KursplanListDTO)
Java 8 JPA版本:2.1 JPA实现:Hibernate 5
答案 0 :(得分:0)
查询的结果始终是一个表。因此,无法在构造函数中获取Collection。
规范定义了标识变量,使它们代表实例,而不是集合。
在此处阅读更多内容:https://martinelli.ch/2009/06/02/jpa-constructor-expression-quiz/