ORM 映射中的“拥有方”是什么?

新手上路,请多包涵

拥有方 到底是什么意思?一些映射示例( 一对多、一对一、多对一)的解释是什么?

以下文字摘自 Java EE 6 文档中对 @OneToOne 的描述。您可以在其中看到概念 拥有方

定义与具有一对一多重性的另一个实体的单值关联。通常不需要显式指定关联的目标实体,因为它通常可以从被引用对象的类型中推断出来。如果关系是双向的, 则非拥有方 必须使用 OneToOne 注释的 mappedBy 元素来指定拥有方的关系字段或属性。

原文由 Just a learner 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 334
2 个回答

为什么拥有方的概念是必要的:

双向关系的拥有方的想法来自这样一个事实,即在关系数据库中没有像对象那样的双向关系。在数据库中,我们只有单向关系——外键。

“拥有方”这个名字的原因是什么?

Hibernate 跟踪的关系的拥有方是在数据库中 拥有 外键的关系的一方。

拥有方的概念解决了什么问题?

声明拥有方的情况下映射的两个实体为例:

 @Entity
@Table(name="PERSONS")
public class Person {
    @OneToMany
    private List<IdDocument>  idDocuments;
}

@Entity
@Table(name="ID_DOCUMENTS")
public class IdDocument {
    @ManyToOne
    private Person person;
}

从面向对象的角度来看,此映射定义的不是一个双向关系,而是 两个 独立的单向关系。

该映射不仅会创建表 PERSONSID_DOCUMENTS ,还会创建第三个关联表 PERSONS_ID_DOCUMENTS

 CREATE TABLE PERSONS_ID_DOCUMENTS
(
  persons_id bigint NOT NULL,
  id_documents_id bigint NOT NULL,
  CONSTRAINT fk_persons FOREIGN KEY (persons_id) REFERENCES persons (id),
  CONSTRAINT fk_docs FOREIGN KEY (id_documents_id) REFERENCES id_documents (id),
  CONSTRAINT pk UNIQUE (id_documents_id)
)

请注意主键 pk ID_DOCUMENTS 上。在这种情况下,Hibernate 独立地跟踪关系的两边:如果您将文档添加到关系 Person.idDocuments ,它会在关联表中插入一条记录 PERSON_ID_DOCUMENTS

另一方面,如果我们调用 idDocument.setPerson(person) ,我们会更改表 ID_DOCUMENTS 上的外键 person_id。 Hibernate 在数据库上创建 两个 单向(外键)关系,以实现 一个 双向对象关系。

拥有方的概念如何解决问题:

很多时候我们想要的只是表上的外键 ID_DOCUMENTS 指向 PERSONS 而不是额外的关联表。

为了解决这个问题,我们需要配置 Hibernate 停止跟踪关系 Person.idDocuments 上的修改。 Hibernate 应该只跟踪关系的 另一IdDocument.person ,为此我们添加 mappedBy

 @OneToMany(mappedBy="person")
private List<IdDocument>  idDocuments;

mappedBy 是什么意思?

这意味着:“关系这一端的修改已经 映射到 关系 IdDocument.person 的另一端,因此无需在额外的表中单独跟踪它。”

是否有任何 GOTCHAs,后果?

使用 mappedBy ,如果我们只调用 person.getDocuments().add(document)ID_DOCUMENTS 中的外键将 不会 链接到新文档,因为这不是关系的拥有/跟踪方!

要将文档链接到新人,您需要显式调用 document.setPerson(person) ,因为这是关系的 _拥有方_。

使用 mappedBy 时,开发人员有责任知道什么是拥有方,并更新关系的正确方以触发数据库中新关系的持久性。

原文由 Angular University 发布,翻译遵循 CC BY-SA 4.0 许可协议

您可以想象 拥有方 是引用另一方的实体。在您的摘录中,您具有一对一的关系。因为它是一个 对称 关系,你最终会得到如果对象 A 与对象 B 相关,那么反之亦然。

这意味着将对对象 B 的引用保存到对象 A 中并将对对象 A 的引用保存到对象 B 中将是多余的:这就是为什么您选择哪个对象“拥有”另一个引用它的对象。

当你有一对多关系时,与“多”部分相关的对象将是拥有方,否则你将不得不存储从单个对象到多个对象的许多引用。为避免这种情况,第二类中的每个对象都将有一个指向它们所引用的单个对象的指针(因此它们是拥有方)。

对于多对多关系,因为无论如何您都需要一个单独的映射表,所以不会有任何拥有方。

总之, 拥有方 是引用另一方的实体。

原文由 Jack 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题