JPA:何时选择多值关联与元素集合映射

Jan*_*Jan 36 java orm hibernate jpa jpa-2.0

我想更好地理解两者之间的差异

(1)传统的多值关系/关联

   @Entity -> @OneToMany -> @Entity
Run Code Online (Sandbox Code Playgroud)

(2)JPA2 可嵌入(和基本)类型的集合

  @Entity -> @ElementCollection -> @Embeddable
Run Code Online (Sandbox Code Playgroud)

我看到了语法差异,但想知道是否还有性能影响.在幕后,数据库实现看起来非常相似.

直觉上,我通常会使用@ElementCollectionfor 组合场景.但即使这感觉非常相似CascadeType=DELETE.

我错过了这里的精华吗?出于某些目的,一个比另一个更有效吗?

谢谢你,J.

Pas*_*ent 18

直观地说,我通常会将@ElementCollection用于合成场景.但即使这种感觉与CascadeType = DELETE非常相似

它们相似,但略有不同.Java Persistence wikibook中的ElementCollection页面很好地总结了它:

Emdedded Collections

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

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

也可以看看


Art*_*ald 8

JPA规范很清楚

无法独立于父对象查询,保留,合并嵌入式项.它们是严格的私有(依赖)对象

您应该谨慎使用,因为它的生命周期受拥有实体实例的生命周期的限制.因此,如果您持久化/合并/删除您拥有的实体实例,则将保留/合并/删除其所有embeddables实例

假设你做了类似的事情

/**
  * Let's suppose owning contains SIX embeddables instances
  */
Owning owning = manager.find(Owining.class, owningId);
Run Code Online (Sandbox Code Playgroud)

因此,您只需在视图层修改您的拥有实体并提交更改即可.您可以使用检索您的Owning实体

/**
  * Usually your web framework Takes care of binding your submitted data
  */
Owning owning = new Owning();
owning.setProperty(request.getParameter("property"));
Run Code Online (Sandbox Code Playgroud)

然后,您可以合并您提交的数据,并且您认为您的embeddables实例已存储在数据库中.好的,我们等着瞧

如上所示,您(或您的Web框架)刚刚检索到Owning属性,对吧??? 所以你的owning.getElementList()是空的.因为owning.getElementList()为空,JPA将删除其所有embeddables实例.记住这一点.

通常,可嵌入类与其拥有实体之外没有其他关系.当使用一组嵌入式时,JPA 总是在保存/更新之前选择,因为它需要使用其equals方法逐个进行比较.因此,在使用Set集合时,您需要一致的equals实现.

在这里你可以看到它在Hibernate中的对应物.