我想更好地理解
之间的区别(1)传统的多值关系/关联
@Entity -> @OneToMany -> @Entity
和
(2)JPA2 可嵌入(和基本)类型的集合
@Entity -> @ElementCollection -> @Embeddable
我看到了语法差异,但想知道是否还存在性能影响。在幕后,数据库实现看起来非常相似。
直观地说,我通常会将@ElementCollection
用于合成场景。但即便如此,也感觉与CascadeType=DELETE
非常相似。
我错过了这里的精华吗?出于某些目的,一个比另一个更有效吗?
谢谢你,J。
答案 0 :(得分:16)
直观地说,我通常会将@ElementCollection用于合成场景。但即使这种感觉与CascadeType = DELETE
非常相似
它们很相似,但略有不同。来自ElementCollection wikibook的Java Persistence页面总结得非常好:
Emdedded Collections
ElementCollection
映射可以 用来定义一个集合Embeddable
个对象。这不是一个Embeddable
个对象的典型用法 对象不是嵌入中的 源对象的表,但存储在 单独的收集表。这是 类似于OneToMany
,除了 目标对象是Embeddable
一个Entity
。这允许收藏 简单的对象很容易 定义,不需要简单 用于定义Id
或ManyToOne
的对象 逆映射。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中看到它的对应物。