10
  1. 双方向の多対多の関係で MappedBy を設定する理由は何ですか?
  2. あるテーブルにかなりの量のレコードがあり、他のテーブルには少数のレコードがある場合、どちら側にmappedByを配置するのが良いでしょうか?
4

2 に答える 2

22

これは実際には良い質問であり、「所有」エンティティの概念を理解するのに役立ちます。(双方向の関係で) 両側に を持たないようにしたい場合はjoin tables、良い考えですが、mappedBy=一方の側に要素を配置する必要があります。

があるかどうかは、注釈の要素join tableによって制御されます。アノテーションのmappedByのJavadocには次のように書かれています:mappedBy="name"@ManyToManyManyToMany

リレーションシップを所有するフィールド。リレーションシップが一方向でない限り、必須です。

あなたの(双方向)例では、@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が必要であると書かれています。mappedBySideA にリレーションシップを「所有」させることにした場合は、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追加または削除してリレーションシップを更新しますが、保持したい のインスタンスのリストがある場合は、リストを繰り返し処理し、リスト内の の各インスタンスを変更する必要があります。SideBSideASideASideBSideA

いつものように、SQL ログを有効にして、データベースで何が起こっているかを確認することをお勧めします。

編集:設定なしで単一の結合テーブルのみを作成する永続化プロバイダーがある場合はmappedBy、ドキュメントを確認して、どちらの側が関係を「所有」しているかを確認する必要があります。どちらかまたは両方の側がそれを所有しておらず、どちらかまたはどちらかの側を更新するとエンティティが永続化される可能性があります。

参考文献:

単方向アソシエーションと双方向アソシエーションの違いは何ですか? .

双方向の関係における関係所有者とは何を意味しますか? .

ORM マッピングの「所有側」とは何ですか? .

toString()で無限再帰を防ぐ最も効率的な方法は? .

于 2016-05-19T00:46:12.590 に答える
1

mappedByBIDIRECTIONAL リレーションの両側をリンクします。何かが持っているレコードの数にmappedBy基づくのではなく、リレーションの OWNER を設定します (別名オブジェクト指向設計)。この情報は、JPA のチュートリアルとドキュメントに記載されています。

于 2016-05-16T05:38:57.780 に答える