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

拥有方意味着什么? 什么是一些映射实例的解释( 一对多,一对一,多对一 )?

以下文字摘自Java EE 6文档中@OneToOne的描述。 你可以看到它拥有一面的概念。

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

你可以想象, 拥有的一方是指另一方的实体。 在你的节选中,你有一个一对一的关系。 因为它是一个对称关系,所以如果对象A与对象B有关系,那么反之亦然。

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

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

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

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

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

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

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

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的angular度来看,这个映射不是定义一个双向关系,而是定义两个不同的单向关系。

映射不仅会创build表ID_DOCUMENTSID_DOCUMENTS ,还会创build第三个关联表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) ) 

仅注意ID_DOCUMENTS上的主键pk 。 在这种情况下,Hibernate会独立跟踪关系的两个方面:如果将关联文档添加到Person.idDocuments ,它将在关联表PERSON_ID_DOCUMENTS插入一条logging。

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

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

很多时候我们想要的仅仅是ID_DOCUMENTS表中的一个外键,用于表示人员和附加关联表。

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

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

这是什么意思映射?

这意味着像这样:“关系的这一方的修改已经被映射到关系IdDocument.person的另一端,所以不需要在一个额外的表中单独追踪它。

有没有GOTCHA,后果?

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

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

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