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

时间:2010-05-01 11:11:48

标签: java hibernate orm jpa mapping

拥有方 究竟是什么意思?一些映射示例的解释是什么( 一对多,一对一,多对一 )?

以下文字摘自Java EE 6文档中 @OneToOne 的说明。您可以在其中看到 拥有方 这一概念。

  

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

3 个答案:

答案 0 :(得分:152)

为什么必须拥有一个拥有方的概念:

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

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

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;
}

从OO的角度来看,这种映射不是一个双向关系,而是两个单独的单向关系。

映射不仅会创建表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_DOCUMENTSPERSONS的外键和额外的关联表。

要解决此问题,我们需要配置Hibernate以停止跟踪关系Person.idDocuments上的修改。 Hibernate应该只跟踪关系IdDocument.person其他方面,为此我们添加 mappedBy

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

它是什么意思mappedBy?

  

这意味着:“关系这一方的修改已经映射   关系IdDocument.person的另一面,所以没必要   在额外的表格中单独跟踪它。“

是否有任何GOTCHA,后果?

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

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

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

答案 1 :(得分:128)

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

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

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

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

总之,拥有方是指向另一方的实体。

答案 2 :(得分:0)

双向关系必须遵循这些规则。

双向关系的反面必须使用@OneToOne、@OneToMany 或@ManyToMany 批注的mappedBy 元素来引用其拥有方。 mappingBy 元素指定实体中作为关系所有者的属性或字段。

多对一双向关系的多面不能定义mappedBy元素。 多方始终是关系的拥有方。(根据 Oracle 文档:https://docs.oracle.com/cd/E19798-01/821-1841/bnbqi/index.html

对于一对一的双向关系,拥有方对应于包含相应外键的一方。

对于多对多的双向关系,任何一方都可能是拥有方。