Java ORM 映射中的“拥有方”是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2749689/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the "owning side" in an ORM mapping?
提问by Just a learner
What exactly does the owning sidemean? 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 @OneToOnein Java EE 6 documentation. You can see the concept owning sidein 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 sidemust use the mappedBy element of the OneToOne annotation to specify the relationship field or property of the owning side.
定义到另一个具有一对一多重性的实体的单值关联。通常不需要明确指定关联的目标实体,因为它通常可以从被引用的对象类型推断出来。如果关系是双向的,则非拥有方必须使用 OneToOne 注释的mappedBy 元素来指定拥有方的关系字段或属性。
采纳答案by Angular University
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 ownsthe foreign key in the database.
Hibernate 跟踪的关系的拥有方是拥有数据库中外键的关系方。
What is the problem that the notion of owning side solves?
拥有方的概念解决了什么问题?
Take an example of two entities mapped withoutdeclaring 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 twoseparate uni-directional relations.
从面向对象的角度来看,该映射定义的不是一个双向关系,而是两个单独的单向关系。
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
.
注意主键pk
上ID_DOCUMENTS
唯一的。在这种情况下,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 twounidirectional (foreign key) relations on the database, to implement onebidirectional object relation.
另一方面,如果我们调用idDocument.setPerson(person)
,我们会更改 table 上的外键 person_id ID_DOCUMENTS
。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 PERSONS
and 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 otherside of the relation IdDocument.person
, and to do so we add mappedBy:
为了解决这个问题,我们需要配置 Hibernate 来停止跟踪对关系的修改Person.idDocuments
。Hibernate 应该只跟踪关系的另一端IdDocument.person
,为此我们添加了mappingBy:
@OneToMany(mappedBy="person")
private List<IdDocument> idDocuments;
What does it mean mappedBy ?
是什么意思 mappingBy ?
This means something like: "modifications on this side of the relation are already Mapped Bythe 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 NOTbe linked to the new document, because this is not the owning /tracked side of the relation!
使用mappingBy,如果我们只调用person.getDocuments().add(document)
,外键 inID_DOCUMENTS
将不会链接到新文档,因为这不是关系的拥有 /tracked 一侧!
To link the document to the new person, you need to explicitly call document.setPerson(person)
, because that is the owning sideof 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.
在使用mappingBy 时,开发人员有责任知道拥有方是什么,并更新关系的正确方以触发新关系在数据库中的持久化。
回答by Hyman
You can imagine that the owning sideis the entity that has the reference to the other one. In your excerpt, you have an one-to-one relationship. Since it's a symmetricrelation, 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.
这意味着将对象 B 的引用保存到对象 A 中,而在对象 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).
当您拥有一对多关系时,与“多”部分相关的对象将成为拥有方,否则您将不得不存储从单个对象到多个对象的多个引用。为了避免这种情况,第二个类中的每个对象都将有一个指向它们所引用的单个对象的指针(因此它们是拥有方)。
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 sideis the entity that has the reference to the other.
总之,拥有方是具有对另一方的引用的实体。