【发布时间】:2018-01-15 11:44:53
【问题描述】:
尝试将 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();
实体('Kursplan'):
...
@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'.
显然是“。”在 col_3_0_ 上看起来不正确。
如果我从多选和 DTO 构造函数中省略了“参与者”,则它可以工作(其他数据按应有的方式读入 DTO)。
那么我可以做些什么来制定标准,让我将元素集合的内容放入值对象(在我的例子中是 KursplanListDTO)
Java 8 JPA 版本:2.1 JPA 实现:Hibernate 5
【问题讨论】:
-
查询的结果总是一个表。所以不可能在构造函数中得到一个Collection
-
这是否意味着将元素集合(或任何集合)放入 DTO 的唯一方法是(在我的情况下)遍历结果列表和每个项目/行的“子”查询对于参与者列表,然后使用参与者列表更新 DTO(通过设置器)?没有 jpa/hbernate 魔法来拯救?
-
好的,谢谢你的帮助!
标签: java hibernate jpa criteria-api