- 在双向多对多关系中设置 MappedBy 的原因是什么?
- 当一个表有大量记录,而另一个表有几个记录时,哪一边放 mappedBy 更好?
> 这实际上是一个很好的问题,它有助于理解"拥有"实体的概念。如果你想防止双方(在双向关系中(都有join tables
,一个好主意,那么你需要在一侧有一个mappedBy=
元素。
是否存在join table
由@ManyToMany
注释的mappedBy="name"
元素控制。Javadoc for mappedBy for the ManyToMany
注解说:
拥有关系的字段。除非关系是单向的,否则是必需的。
对于您的(双向(示例,如果只有两个@ManyToMany
注释并且没有mappedBy=
元素,则默认值将有两个Entity
表和两个Join Tables
:
Hibernate: create table SideA (id bigint not null, primary key (id))
Hibernate: create table SideA_SideB (sidea_id bigint not null, sidebs_id bigint not null, primary key (sidea_id, sidebs_id))
Hibernate: create table SideB (id bigint not null, primary key (id))
Hibernate: create table SideB_SideA (sideb_id bigint not null, sideas_id bigint not null, primary key (sideb_id, sideas_id))
虽然这是说每个实体"拥有"其ManyToMany
关系,但在典型用例中,额外的join table
是多余的,Javadoc 说你需要一个mappedBy
注释。如果我决定让 SideA "拥有"关系,那么我将 mappedBy=
元素添加到 SideB 实体以指定它不拥有该关系:
@Entity
public class SideA {
@ManyToMany
Set<SideB> sidebs;
}
@Entity
public class SideB {
@ManyToMany(mappedBy="sidebs")
Set<SideA> sideas;
}
由于 SideB 实体不再拥有其ManyToMany
关系,因此不会创建额外的JoinTable
:
Hibernate: create table SideA (id bigint not null, primary key (id))
Hibernate: create table SideB (id bigint not null, primary key (id))
Hibernate: create table SideA_SideB (sideas_id bigint not null, sidebs_id bigint not null, primary key (sideas_id, sidebs_id))
这对开发人员很重要,因为他或她必须了解,除非将关系添加到拥有实体(在本例中为SideA
实体(,否则不会保留任何关系。
因此,如果您有bidirectional
ManyToMany
关系,这意味着您对所涉及的两个实体都有ManyToMany
,那么您应该根据 Javadoc 在其中之一上添加一个mappedBy="name"
,并避免出现冗余join table
。
至于哪一方是拥有实体,没有正确的答案,这取决于你的系统认为什么是最好的。只有当条目被放入拥有方时,这种关系才会持续存在,所以你必须问问自己,你更常更改SideA's
列表还是SideB's
列表。如果SideA
拥有该关系,则您可以通过在SideA
实例中添加或删除SideB
实例来更新关系,但是,如果您有要保留的SideB
的SideA
实例列表,则需要循环访问该列表并更改列表中的每个SideA
实例。
与往常一样,启用 sql 日志并查看数据库中发生的情况始终是一个好主意:
编辑:如果你有一个持久性提供程序,它只创建一个没有mappedBy
设置的联接表,那么你必须检查文档以查看哪一方"拥有"关系。可能是双方都不拥有它,并且更新任何一方或任何一方都不会保留该实体。
引用:
单向关联和双向关联有什么区别?
关系所有者在双向关系中是什么意思?
ORM映射中的"拥有方"是什么?
防止 toString(( 中无限递归的最有效方法?
mappedBy
链接双向关系的两侧。你把mappedBy
放在关系的所有者身上,而不是基于某物有多少条记录(又名面向对象设计(。您可以在任何 JPA 教程和文档中找到此信息。