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

时间:2022-09-11 23:46:25

What exactly does the owning side mean? What is an explanation with some mapping examples (one to many, one to one, many to one)?

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

The following text is an excerpt from the description of @OneToOne in Java EE 6 documentation. You can see the concept owning side in it.

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

Defines a single-valued association to another entity that has one-to-one multiplicity. It is not normally necessary to specify the associated target entity explicitly since it can usually be inferred from the type of the object being referenced. If the relationship is bidirectional, the non-owning side must use the mappedBy element of the OneToOne annotation to specify the relationship field or property of the owning side.

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

2 个解决方案

#1


102  

You can imagine that the owning side is the entity that has the reference to the other one. In your excerpt, you have an one-to-one relationship. Since it's a symmetric relation, you'll end up having that if object A is in relation with object B then also the vice-versa is true.

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

This means that saving into object A a reference to object B and saving in object B a reference to object A will be redundant: that's why you choose which object "owns" the other having the reference to it.

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

When you have got an one-to-many relationship, the objects related to the "many" part will be the owning side, otherwise you would have to store many references from a single object to a multitude. To avoid that, every object in the second class will have a pointer to the single one they refer to (so they are the owning side).

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

For a many-to-many relationship, since you will need a separate mapping table anyway there won't be any owning side.

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

In conclusion the owning side is the entity that has the reference to the other.

总之,拥有方是指对方的实体。

#2


116  

Why is the notion of a owning side necessary:

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

The idea of a owning side of a bidirectional relation comes from the fact that in relational databases there are no bidirectional relations like in the case of objects. In databases we only have unidirectional relations - foreign keys.

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

What is the reason for the name 'owning side'?

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

The owning side of the relation tracked by Hibernate is the side of the relation that owns the foreign key in the database.

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

What is the problem that the notion of owning side solves?

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

Take an example of two entities mapped without declaring a owning side:

举例说明两个实体的映射而不声明拥有方:

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

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

From a OO point of view this mapping defines not one bi-directional relation, but two separate uni-directional relations.

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

The mapping would create not only tables PERSONS and ID_DOCUMENTS, but would also create a third association table PERSONS_ID_DOCUMENTS:

映射不仅会创建表PERSONS和ID_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)
)

Notice the primary key pk on ID_DOCUMENTS only. In this case Hibernate tracks both sides of the relation independently: If you add a document to relation Person.idDocuments, it inserts a record in the association table PERSON_ID_DOCUMENTS.

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

On the other hand, if we call idDocument.setPerson(person), we change the foreign key person_id on table ID_DOCUMENTS. Hibernate is creating two unidirectional (foreign key) relations on the database, to implement one bidirectional object relation.

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

How the notion of owning side solves the problem:

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

Many times what we want is only a foreign key on table ID_DOCUMENTS towards PERSONSand the extra association table.

很多时候我们想要的只是表ID_DOCUMENTS上的外键和PERSONS以及额外的关联表。

To solve this we need to configure Hibernate to stop tracking the modifications on relation Person.idDocuments. Hibernate should only track the other side of the relation IdDocument.person, and to do so we add mappedBy:

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

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

What does it mean mappedBy ?

它是什么意思mappedBy?

This means something like: "modifications on this side of the relation are already Mapped By the other side of the relation IdDocument.person, so no need to track it here separately in an extra table."

这意味着:“关系的这一侧的修改已经被关系IdDocument.person的另一侧映射,所以不需要在额外的表中单独跟踪它。”

Are there any GOTCHAs, consequences?

是否有任何GOTCHA,后果?

Using mappedBy, If we only call person.getDocuments().add(document), the foreign key in ID_DOCUMENTS will NOT be linked to the new document, because this is not the owning /tracked side of the relation!

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

To link the document to the new person, you need to explicitly call document.setPerson(person), because that is the owning side of the relation.

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

When using mappedBy, it is the responsibility of the developer to know what is the owning side, and update the correct side of the relation in order to trigger the persistence of the new relation in the database.

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

#1


102  

You can imagine that the owning side is the entity that has the reference to the other one. In your excerpt, you have an one-to-one relationship. Since it's a symmetric relation, you'll end up having that if object A is in relation with object B then also the vice-versa is true.

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

This means that saving into object A a reference to object B and saving in object B a reference to object A will be redundant: that's why you choose which object "owns" the other having the reference to it.

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

When you have got an one-to-many relationship, the objects related to the "many" part will be the owning side, otherwise you would have to store many references from a single object to a multitude. To avoid that, every object in the second class will have a pointer to the single one they refer to (so they are the owning side).

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

For a many-to-many relationship, since you will need a separate mapping table anyway there won't be any owning side.

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

In conclusion the owning side is the entity that has the reference to the other.

总之,拥有方是指对方的实体。

#2


116  

Why is the notion of a owning side necessary:

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

The idea of a owning side of a bidirectional relation comes from the fact that in relational databases there are no bidirectional relations like in the case of objects. In databases we only have unidirectional relations - foreign keys.

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

What is the reason for the name 'owning side'?

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

The owning side of the relation tracked by Hibernate is the side of the relation that owns the foreign key in the database.

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

What is the problem that the notion of owning side solves?

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

Take an example of two entities mapped without declaring a owning side:

举例说明两个实体的映射而不声明拥有方:

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

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

From a OO point of view this mapping defines not one bi-directional relation, but two separate uni-directional relations.

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

The mapping would create not only tables PERSONS and ID_DOCUMENTS, but would also create a third association table PERSONS_ID_DOCUMENTS:

映射不仅会创建表PERSONS和ID_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)
)

Notice the primary key pk on ID_DOCUMENTS only. In this case Hibernate tracks both sides of the relation independently: If you add a document to relation Person.idDocuments, it inserts a record in the association table PERSON_ID_DOCUMENTS.

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

On the other hand, if we call idDocument.setPerson(person), we change the foreign key person_id on table ID_DOCUMENTS. Hibernate is creating two unidirectional (foreign key) relations on the database, to implement one bidirectional object relation.

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

How the notion of owning side solves the problem:

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

Many times what we want is only a foreign key on table ID_DOCUMENTS towards PERSONSand the extra association table.

很多时候我们想要的只是表ID_DOCUMENTS上的外键和PERSONS以及额外的关联表。

To solve this we need to configure Hibernate to stop tracking the modifications on relation Person.idDocuments. Hibernate should only track the other side of the relation IdDocument.person, and to do so we add mappedBy:

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

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

What does it mean mappedBy ?

它是什么意思mappedBy?

This means something like: "modifications on this side of the relation are already Mapped By the other side of the relation IdDocument.person, so no need to track it here separately in an extra table."

这意味着:“关系的这一侧的修改已经被关系IdDocument.person的另一侧映射,所以不需要在额外的表中单独跟踪它。”

Are there any GOTCHAs, consequences?

是否有任何GOTCHA,后果?

Using mappedBy, If we only call person.getDocuments().add(document), the foreign key in ID_DOCUMENTS will NOT be linked to the new document, because this is not the owning /tracked side of the relation!

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

To link the document to the new person, you need to explicitly call document.setPerson(person), because that is the owning side of the relation.

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

When using mappedBy, it is the responsibility of the developer to know what is the owning side, and update the correct side of the relation in order to trigger the persistence of the new relation in the database.

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