MappedBy in bidirectional @ManyToMany: what is the reason

  • What is the reason for installing MappedBy in a many-to-many bidirectional relationship?
  • When one table has a significant number of records, while others have several, on which side is it better to put mappedBy?
+5
source share
2 answers

This is a really good question, and it helps to understand the concept of a "possessing" entity. If you want both sides (in a bidirectional relation) to have join tables , a good idea, then you need to have the mappedBy= element on one side.

Regardless of whether a join table exists, it is controlled by the mappedBy="name" element of the mappedBy="name" annotation. Javadoc for mappedBy for annotation ManyToMany says :

The field to which the relation belongs. Required if the relation is not unidirectional.

For your (bidirectional) example, if there were only two @ManyToMany annotations and a mappedBy= element, by default there would be 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)) 

Although this suggests that each Entity โ€œownsโ€ its ManyToMany relationship, the extra join table redundant in a typical use case, and Javadoc says you need the mappedBy annotation. If I decide that I have SideA, then I add the mappedBy= element to the mappedBy= entity to indicate that it is not relevant:

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

Since the SideB object is no longer ManyToMany with ManyToMany , an additional 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)) 

This is important for the developer because he or she must understand that no relationship is preserved unless it is added to its own object, in this case, the SideA object. However, since this is a bi-directional relationship, the developer must add both a SideA to SideB.sideas and SideB to SideA.sidebs .

So, if you have a bidirectional ManyToMany relation, which means you have ManyToMany for both objects involved, then you should add mappedBy="name" on one of them according to the Javadoc and avoid the redundant join table . Since it is bidirectional, I donโ€™t think it matters which side you create your owning object owning - it depends on your application preferences. As always, itโ€™s always useful to include SQL logs and see what happens in the database:

References:

What is the difference between unidirectional and bidirectional associations? .

What does a relationship owner in a bidirectional relationship mean? .

What is the "own side" in the ORM mapping? .

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

+8
source

mappedBy connects both sides of a BIDIRECTIONAL relationship. You put mappedBy in the OWNER of the relationship, not based on how many records something has (as an object oriented design). You will find this information in any JPA tutorial and documentation.

+1
source

All Articles