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

Java JPA:何时选择多值关联与元素集合映射,java,hibernate,orm,jpa,jpa-2.0,Java,Hibernate,Orm,Jpa,Jpa 2.0,我想更好地理解两者之间的区别 (1) 传统的多值关系/关联 @Entity -> @OneToMany -> @Entity @Entity -> @ElementCollection -> @Embeddable 及 (2) JPA2可嵌入(和基本)类型的集合 @Entity -> @OneToMany -> @Entity @Entity -> @ElementCollection -> @Embeddable 我看

我想更好地理解两者之间的区别

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

   @Entity -> @OneToMany -> @Entity
  @Entity -> @ElementCollection -> @Embeddable

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

   @Entity -> @OneToMany -> @Entity
  @Entity -> @ElementCollection -> @Embeddable
我看到了语法上的差异,但不知道是否也有性能方面的影响。在后台,数据库实现看起来非常相似

直观地说,我通常会在合成场景中使用
@ElementCollection
。但即使这样,感觉也非常类似于
CascadeType=DELETE

我错过了这里的精华吗?在某些方面,一个比另一个更有效率吗

谢谢你,J

直觉上,我通常会在合成场景中使用@ElementCollection。但即使这样,感觉也非常类似于CascadeType=DELETE

它们是相似的,只是有些细微的差别。维基百科的页面对其进行了很好的总结:

可以创建
ElementCollection
映射 用于定义
可嵌入对象。这不是一个好主意
可嵌入对象的典型用法
对象未嵌入到
源对象的表,但存储在
单独的收集台。这是
类似于一个
OneToMany
,除了 目标对象是可嵌入的
一个
实体的
。这允许收集 将简单对象的 定义,不需要简单的 对象来定义
Id
ManyToOne
逆映射<代码>元素集合
can 还重写映射或表 为了他们的收藏,所以你可以 多个实体引用同一个实体
可嵌入
类,但每个存储 它们的从属对象在一个单独的 桌子

使用
ElementCollection
而不是
OneToMany
是目标对象吗 无法查询、保留、合并 独立于其父对象。 它们完全是私有的 (从属)对象,与
嵌入式
映射。它们是无
cascade
元素集合
上的选项 目标对象始终保持不变, 与其父级合并、删除。
ElementCollection
仍然可以使用 获取类型,默认为
LAZY
与其他集合映射相同

另见

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框架)刚刚检索到拥有的属性,对吗???因此,您拥有的.getElementList()为空。由于owning.getElementList()为空,JPA将删除其所有可嵌入实例。记住这一点

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

您可以在Hibernate中看到它的对应项

@Jan在这里看一下构图,你会发现@ElementCollection更适合哪里