- 双方向の多対多の関係で MappedBy を設定する理由は何ですか?
- あるテーブルにかなりの量のレコードがあり、他のテーブルには少数のレコードがある場合、どちら側にmappedByを配置するのが良いでしょうか?
2 に答える
これは実際には良い質問であり、「所有」エンティティの概念を理解するのに役立ちます。(双方向の関係で) 両側に を持たないようにしたい場合はjoin tables
、良い考えですが、mappedBy=
一方の側に要素を配置する必要があります。
があるかどうかは、注釈の要素join table
によって制御されます。アノテーションのmappedByのJavadocには次のように書かれています:mappedBy="name"
@ManyToMany
ManyToMany
リレーションシップを所有するフィールド。リレーションシップが一方向でない限り、必須です。
あなたの(双方向)例では、@ManyToMany
注釈が2つしかなく、mappedBy=
要素がない場合、デフォルトには2つのEntity
テーブルと2つの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
関係を「所有」していると言っていますが、通常のユースケースでは余分なものは冗長であり、Javadoc には注釈join table
が必要であると書かれています。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
関係がある場合、つまり両方のエンティティが関与している場合は、Javadoc に従ってそれらのいずれかにManyToMany
を追加し、冗長な を避ける必要があります。mappedBy="name"
join table
どちら側を所有エンティティにするかについては、正解はありません。システムが最適と考える方法によって異なります。SideA's
この関係は、エントリが所有側に配置された場合にのみ保持されるため、リストまたはリストを変更することが多いかどうかを自問する必要がありますSideB's
。がリレーションシップを所有している場合は、インスタンスにインスタンスをSideA
追加または削除してリレーションシップを更新しますが、保持したい のインスタンスのリストがある場合は、リストを繰り返し処理し、リスト内の の各インスタンスを変更する必要があります。SideB
SideA
SideA
SideB
SideA
いつものように、SQL ログを有効にして、データベースで何が起こっているかを確認することをお勧めします。
編集:設定なしで単一の結合テーブルのみを作成する永続化プロバイダーがある場合はmappedBy
、ドキュメントを確認して、どちらの側が関係を「所有」しているかを確認する必要があります。どちらかまたは両方の側がそれを所有しておらず、どちらかまたはどちらかの側を更新するとエンティティが永続化される可能性があります。
参考文献:
mappedBy
BIDIRECTIONAL リレーションの両側をリンクします。何かが持っているレコードの数にmappedBy
基づくのではなく、リレーションの OWNER を設定します (別名オブジェクト指向設計)。この情報は、JPA のチュートリアルとドキュメントに記載されています。