【问题标题】:Read content from ElementCollection annotated attribute into value object attribute将 ElementCollection 注释属性中的内容读取到值对象属性中
【发布时间】: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


【解决方案1】:

查询的结果始终是一个表。所以无法在构造函数中获取 Collection。

规范定义了标识变量,以便它们代表实例,而不是集合。

在这里阅读更多:https://martinelli.ch/2009/06/02/jpa-constructor-expression-quiz/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    • 2020-07-13
    • 1970-01-01
    • 2013-09-11
    相关资源
    最近更新 更多