JPA 2 – 在CriteriaQuery中使用@ElementCollection

@Entity public class Person { @ElementCollection private List locations; [...] } @Embeddable public class Location { private Integer dummy; private Date creationDate; [...] } 

鉴于以下结构,我想执行以下SQL的HQL或CriteriaQuery等价物:

 SELECT l.* FROM Location l INNER JOIN Person p ON (p.id = l.person_id) WHERE p.id = ? AND l.creationDate > ? 

我想找回与给定人员相关联的位置列表,其创建日期在给定人员之后。

提前致谢!

标记

编辑***:我编辑了SQL,因为它有点误导。 我不想独立查询位置。

这是不可能的,您无法查询Embeddable 。 来自JPA Wikibook:

嵌入式集合

ElementCollection映射可用于定义Embeddable对象的集合。 这不是Embeddable对象的典型用法,因为对象未嵌入源对象的表中,而是存储在单独的集合表中。 这类似于OneToMany ,但目标对象是Embeddable而不是Entity 。 这允许容易地定义简单对象的集合,而不需要简单对象来定义IdManyToOne逆映射。 ElementCollection还可以覆盖其集合的映射或表,因此您可以让多个实体引用相同的Embeddable类,但每个实体都将其依赖对象存储在单独的表中。

使用ElementCollection而不是OneToMany的限制是无法独立于父对象查询 ,保持,合并目标对象。 它们是严格的私有(依赖)对象,与Embedded映射相同。 ElementCollection上没有级联选项,目标对象始终与父级一起保持,合并,删除。 ElementCollection仍然可以使用fetch类型,默认为LAZY,与其他集合映射相同。

要实现您的目标,请使用OneToManyEntity而不是ElementCollectionEmbeddable 。 或者更改您的方法并查询Person

Pascal的回复中的关键词是

目标对象无法独立于其父对象进行查询,保持,合并

因为你依赖于父对象,你应该可以使用像…这样的东西来做到这一点。

SELECT p FROM PERSON, IN (p.locations) WHERE p.id = ?1 AND locations = ?2

(根据执行“MEMBER OF”的回复查询JP-QL(JPA 2.0)中的’ElementCollection’地图字段 – 实际上是Map @ElementCollection,这正是我正在寻找的答案!)