MappedBy双向@ManyToMany:

时间:2016-05-15 20:10:22

标签: jpa many-to-many mappedby

  1. 在双向多对多关系中设置MappedBy的原因是什么?
  2. 当一个表有大量记录,而其他表有少量时,哪一方最好放置mappedBy?

2 个答案:

答案 0 :(得分:13)

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

是否存在join tablemappedBy="name"注释的@ManyToMany元素控制。 Javadoc for mappedBy for the ManyToMany annotation says

  

拥有这种关系的领域。除非关系是单向的,否则是必需的。

对于您的(双向)示例,如果只有两个@ManyToMany注释且没有mappedBy=元素,则默认情况下将有两个Entity表和两个Join Tables:< / p>

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个实例的列表SideB你想要坚持下去,你需要遍历列表并改变列表中SideA的每个实例。

与往常一样,启用sql日志并查看数据库中发生的情况始终是个好主意:

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

参考文献:

What is the difference between Unidirectional and Bidirectional associations?

What does relationship owner means in bidirectional relationship?

What is the “owning side” in an ORM mapping?

Most efficient way to prevent an infinite recursion in toString()?

答案 1 :(得分:1)

mappedBy链接双向关系的两边。您将mappedBy放在关系的OWNER上,而不是基于某些记录有多少(也就是面向对象的设计)。您可以在任何JPA教程和文档中找到此信息。