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

时间:2010-08-05 19:59:02

标签: java hibernate orm jpa jpa-2.0

我想更好地理解

之间的区别

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

   @Entity -> @OneToMany -> @Entity

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

  @Entity -> @ElementCollection -> @Embeddable

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

直观地说,我通常会将@ElementCollection用于合成场景。但即便如此,也感觉与CascadeType=DELETE非常相似。

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

谢谢你,J。

2 个答案:

答案 0 :(得分:16)

  

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

非常相似

它们很相似,但略有不同。来自ElementCollection wikibook的Java Persistence页面总结得非常好:

  

Emdedded Collections

     

ElementCollection映射可以   用来定义一个集合   Embeddable个对象。这不是一个   Embeddable个对象的典型用法   对象不是嵌入中的   源对象的表,但存储在   单独的收集表。这是   类似于OneToMany,除了   目标对象是Embeddable   一个Entity。这允许收藏   简单的对象很容易   定义,不需要简单   用于定义IdManyToOne的对象   逆映射。 ElementCollection可以   也覆盖映射或表   对于他们的收藏,所以你可以拥有   多个实体引用相同的内容   Embeddable课程,但每个商店   他们的依赖对象在一个单独的   表

     

使用的限制   ElementCollection代替   OneToMany是目标对象   无法查询,坚持,合并   独立于其父对象。   他们是严格的私人所有   (依赖)对象,与a相同   Embedded映射。他们不是cascade   ElementCollection上的选项   目标对象始终保持不变,   合并,与父母一起删除。   ElementCollection仍然可以使用   获取类型并默认为LAZY   与其他集合映射相同。

另见

答案 1 :(得分:8)

JPA规范很明确

  

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

您应该小心使用 ,因为它的生命周期受拥有实体实例的生命周期限制。因此,如果您持久/合并/删除您拥有的实体实例,所有嵌入式实例将被持久化/合并/删除

假设您执行类似

的操作
/**
  * Let's suppose owning contains SIX embeddables instances
  */
Owning owning = manager.find(Owining.class, owningId);

因此,您在视图层修改只是您的拥有实体并提交更改。您可以使用

检索您的Owning实体
/**
  * Usually your web framework Takes care of binding your submitted data
  */
Owning owning = new Owning();
owning.setProperty(request.getParameter("property"));

然后,您可以合并您提交的数据,然后您认为您的嵌入式实例存储在数据库中。好吧,让我们看看

如上所示您(或您的网络框架)刚刚检索到拥有属性,对吧???所以你的owning.getElementList()是空的。由于owning.getElementList()为空, JPA将删除其所有可嵌入实例。记住这一点。

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

Here你可以在Hibernate中看到它的对应物。