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

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

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

@Entity -> @OneToMany -> @Entity 

(2) embedded式(和基本)types的JPA2 集合

  @Entity -> @ElementCollection -> @Embeddable 

我看到了语法上的差异,但不知道是否也有性能影响 。 在引擎盖下,数据库实现看起来非常相似。

直觉上,我通常使用@ElementCollection 组合场景 。 但即使如此,感觉非常类似CascadeType=DELETE

我在这里错过了本质吗? 为了某些目的,一个比另一个更有效率吗?

谢谢J.

直觉上,我通常使用@ElementCollection组合场景。 但即使如此,感觉非常类似CascadeType = DELETE

他们是相似的,有一些细微的差别。 Java Persistence wikibook的ElementCollection页面总结得非常好:

Emdedded集合

可以使用ElementCollection映射来定义Embeddable对象的集合。 这不是Embeddable对象的典型用法,因为对象没有embedded源对象的表中,而是存储在单独的集合表中。 这与OneToMany类似,只不过目标对象是Embeddable而不是Entity 。 这允许简单对象的集合被容易地定义,而不需要简单对象来定义IdManyToOne逆映射。 ElementCollection也可以覆盖映射或表的集合,所以你可以让多个实体引用相同的Embeddable类,但是每个实体都将它们的依赖对象存储在一个单独的表中。

使用ElementCollection而不是OneToMany的限制是目标对象不能被查询,保持,独立于它们的父对象合并。 它们是严格私有的(依赖)对象,与Embedded映射相同。 它们在ElementCollection上没有cascade选项,目标对象总是被持久化,合并,与父级一起被移除。 ElementCollection仍然可以使用获取types,默认为LAZY和其他集合映射一样。

也可以看看

  • embedded式(聚合,复合或组件对象)

JPA规范很明确

不能查询,保持embedded式,独立于其父对象进行合并。 他们是严格私有(依赖)对象

您应该谨慎使用因为它的使用寿命是由拥有实体实例的寿命限制的。 所以,如果你坚持/合并/删除你拥有的实体实例,它的所有可embedded实例将被持久/合并/删除

假设你做了类似的事情

 /** * 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")); 

然后你可以合并你提交的数据和你认为你的embedded式实例存储在数据库中 。 好吧,走着瞧

如上所示, 你(或你的web框架)刚刚检索拥有属性 ,正确的? 所以你的owning.getElementList() 是空的 。 由于owning.getElementList()为空, JPA将删除其所有可embedded的实例 。 记住这一点。

通常一个可embedded的类与其拥有的实体没有关系。 而且在使用嵌套集的时候,JPA 总是在保存/更新之前select,因为它需要使用它的equals方法逐一比较。 所以在使用Set集合时需要一致的equals实现

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