10
  1. 在双向多对多关系中设置 MappedBy 的原因是什么?
  2. 当一张表有大量记录,而另一张表有少量记录时,mappedBy 放在哪一侧更好?
4

2 回答 2

22

这实际上是一个很好的问题,它有助于理解“拥有”实体的概念。如果你想防止双方(在双向关系中)有join tables一个好主意,那么你需要mappedBy=在一侧有一个元素。

是否有 ajoin table由注解的mappedBy="name"元素控制。注释的 mappedBy@ManyToMany的Javadoc 说: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在涉及的两个实体上都有,那么您应该mappedBy="name"根据 Javadoc 在其中一个上添加一个,以避免多余的join table.

至于哪一方做拥有实体,没有正确的答案,这取决于你的系统认为什么是最好的。仅当条目放在拥有方时,这种关系才会持续存在,因此您必须问自己是否更常更改SideA's列表或SideB's列表。如果SideA拥有关系,那么您可以通过在实例中添加或删除SideB实例来更新关系,SideA但如果您有一个想要持久的SideA实例列表,则需要遍历列表并更改列表中的每个实例。SideBSideA

与往常一样,启用 sql 日志并查看数据库中发生了什么总是一个好主意:

编辑:如果您有一个仅创建一个没有mappedBy设置的连接表的持久性提供程序,那么您必须检查文档以查看哪一方“拥有”关系。可能是双方都没有或双方都拥有它,并且更新任何一方都不会保留实体。

参考:

单向关联和双向关联有什么区别?.

关系所有者在双向关系中是什么意思?.

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

防止 toString() 中无限递归的最有效方法?.

于 2016-05-19T00:46:12.590 回答
1

mappedBy链接双向关系的双方。您放置mappedBy关系的所有者,而不是基于某物有多少记录(也称为面向对象设计)。您可以在任何 JPA 教程和文档中找到此信息。

于 2016-05-16T05:38:57.780 回答