MappedBy在双向@ManyToMany中:是什么原因 [英] MappedBy in bi-directional @ManyToMany : what is the reason

查看:127
本文介绍了MappedBy在双向@ManyToMany中:是什么原因的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

推荐答案

这实际上是一个好问题,它有助于理解拥有"实体的概念.如果要防止双方(双向关系)都具有join tables,这是一个好主意,则需要在一侧上具有mappedBy=元素.

It's actually a good question, and it helps to understand the concept of an "owning" entity. If you want to prevent both sides (in a bidirectional relationship) from having join tables, a good idea, then you need to have a mappedBy= element on one side.

是否存在join table@ManyToMany批注的mappedBy="name"元素控制. 用于ManyToMany注释的mappingBy的Javadoc说:

Whether or not there is a join table is controlled by the mappedBy="name" element of the @ManyToMany annotation. The Javadoc for mappedBy for the ManyToMany annotation says:

拥有关系的字段.除非关系是单向的,否则为必需.

The field that owns the relationship. Required unless the relationship is unidirectional.

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

For your (bidirectional) example, if there were only two @ManyToMany annotations and no mappedBy= element, the default will have two Entity tables and two 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实体中以指定它不拥有该关系:

While this is saying that each Entity "owns" its ManyToMany relationship, the extra join table is redundant in the typical use case, and the Javadoc says you need a mappedBy annotation. If I decide to have SideA "own" the relationship, then I add the mappedBy= element to the SideB entity to specify that it doesn't own the relationship:

@Entity
public class SideA {
    @ManyToMany
    Set<SideB> sidebs;
}
@Entity
public class SideB {
    @ManyToMany(mappedBy="sidebs")
    Set<SideA> sideas;
}

由于SideB实体不再拥有其ManyToMany关系,因此将不会创建额外的JoinTable:

Since the SideB entity no longer owns its ManyToMany relationship, the extra JoinTable will not be created:

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实体)中,否则没有持久的关系.

This is important to the developer because he or she must understand that no relationship is persisted unless it's added to the owning entity, in this case the SideA entity.

因此,如果您具有bidirectional ManyToMany关系,这意味着您在所涉及的两个实体上都具有ManyToMany,则应按照Javadoc在其中一个实体上添加mappedBy="name",并避免出现冗余join table.

So, if you have a bidirectional ManyToMany relationship, which means you have ManyToMany on both entities involved, then you should add a mappedBy="name" on one of them as per the Javadoc and to avoid having a redundant join table.

关于建立拥有实体的哪一方,没有正确的答案,这取决于您的系统认为最佳.仅当条目放在所有者一方时,该关系才会保留,因此您必须问自己,是更常见的是更改SideA's列表还是SideB's列表.如果SideA拥有该关系,则可以通过在SideA实例中添加或删除SideB实例来更新该关系,但是如果要持久保存SideBSideA实例列表,则需要遍历列表并更改列表中SideA的每个实例.

As to which side to make the owning entity, there is no correct answer, it depends on what your system thinks is best. The relationship will only be persisted when entries are put in the owning side so you have to ask yourself whether you more commonly change a SideA's list or SideB's list. If SideA owns the relationship then you update the relationship by adding or removing SideB instances from a SideA instance but if you had a list of SideA instances for a SideB that you wanted to persist you would need to iterate through the list and alter each instance of SideA in the list.

一如既往,启用sql日志并查看数据库中正在发生的情况总是一个好主意:

As always, it's always a good idea to enable the sql logs and see what's going on in the database:

如果您有一个持久性提供程序,该持久性提供程序仅创建一个没有mappedBy设置的单个联接表,那么您必须检查文档以查看哪一方拥有"该关系.可能是一方或双方都不拥有它,而更新双方或一方都不会保留该实体.

If you have a persistence provider that only creates a single join table with no mappedBy setting then you have to check with the docs to see which side "owns" the relationship. Could be that neither or both sides own it and that updating neither or either side will persist the entity.

参考:

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

关系所有者在双向关系中意味着什么?

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

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

这篇关于MappedBy在双向@ManyToMany中:是什么原因的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆