36

我想更好地理解它们之间的区别

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

   @Entity -> @OneToMany -> @Entity

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

  @Entity -> @ElementCollection -> @Embeddable

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

直觉上,我通常会使用@ElementCollectionfor composition scenario。但即使那样感觉也很相似CascadeType=DELETE

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

谢谢你,J。

4

2 回答 2

18

直观地说,我通常会将@ElementCollection 用于组合场景。但即使这样感觉也很像 CascadeType=DELETE

它们是相似的,有一些细微的差别。Java Persistence wikibook 中的ElementCollection页面很好地总结了它:

嵌入式集合

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

使用 an ElementCollection而不是 a 的限制OneToMany是目标对象不能独立于其父对象进行查询、持久化、合并。它们是严格私有(依赖)的对象,与 Embedded映射相同。它们在 上是没有cascade 选项的ElementCollection,目标对象总是与它们的父对象一起持久化、合并、删除。 ElementCollection仍然可以使用 fetch 类型,并且默认LAZY与其他集合映射相同。

也可以看看

于 2010-08-05T22:32:08.190 回答
8

JPA 规范很明确

嵌入对象不能独立于其父对象进行查询、持久化、合并。它们是严格私有(依赖)的对象

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

假设你做类似的事情

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

因此,您只需在视图层修改的拥有实体并提交您的更改。您通过使用检索您的拥有实体

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

然后您可以合并您提交的数据,并且您认为您的可嵌入实例已存储在数据库中。走着瞧

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

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

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

于 2010-08-05T23:42:56.563 回答