>当一个表有大量记录时,而其他表有少量,哪一方更好地放置mappedBy?
解决方法
是否存在连接表由@ManyToMany注释的mappedBy =“name”元素控制. Javadoc for mappedBy for the ManyToMany
annotation says:
The field that owns the relationship. required unless the relationship is unidirectional.
对于(双向)示例,如果只有两个@ManyToMany注释而没有mappedBy =元素,则默认将具有两个实体表和两个连接表:
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关系,但额外的连接表在典型的用例中是多余的,而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,primary key (sideas_id,sidebs_id))
这对开发人员来说很重要,因为他或她必须明白,除非将关系添加到拥有实体(在本例中为SideA实体),否则不会保持任何关系.
因此,如果您具有双向ManyToMany关系,这意味着您在所涉及的两个实体上都有ManyToMany,那么您应该根据Javadoc在其中一个上添加mappedBy =“name”并避免使用冗余连接表.
至于创建拥有实体的哪一方,没有正确的答案,这取决于您的系统认为最好的.这些关系只会在条目被置于拥有方时保持不变,因此您必须问自己是否更常更改SideA的列表或SideB的列表.如果SideA拥有该关系,那么您可以通过在SideA实例中添加或删除SideB实例来更新关系,但如果您有一个SideB实例,您希望保留SideB实例,则需要遍历列表并更改每个实例. SideA在列表中.
与往常一样,启用sql日志并查看数据库中发生的情况始终是个好主意:
编辑:如果你有一个只创建一个没有mappedBy设置的连接表的持久性提供程序,那么你必须检查文档以查看哪一方“拥有”该关系.可能是双方都不拥有它,并且任何一方或任何一方都不会更新该实体.
参考文献:
@L_301_1@.
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()?.