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


128

正確には何を所有している側の平均?マッピングの例(1対多、1対1、多対1)の説明は何ですか?

次のテキストは、Java EE 6ドキュメントの@OneToOneの説明からの抜粋です。そこにはコンセプトを所有する側のコンセプトが見られます。

1対1の多重度を持つ別のエンティティへの単一値の関連付けを定義します。通常、関連付けられているターゲットエンティティを明示的に指定する必要はありません。参照されるオブジェクトのタイプから推測できるためです。関係が双方向の場合、非所有側はOneToOneアノテーションのmappedBy要素を使用して、所有側の関係フィールドまたはプロパティを指定する必要があります。



5
:私はこの読むまで、私は失われたjavacodegeeks.com/2013/04/...
darga33を

2
外部キー列を持つDBテーブルは、所有側として扱われます。したがって、そのDBテーブルを表すビジネスエンティティは、そのリレーションの所有者(所有側)です。必ずしも必要ではありませんが、ほとんどの場合、Owning-sideには@JoinColumnアノテーションがあります。
ディアブロ

回答:


202

所有側の概念が必要な理由:

双方向リレーションシップの所有側の考え方は、リレーショナルデータベースにはオブジェクトの場合のような双方向リレーションシップがないという事実から来ています。データベースでは、外部キーという単一方向の関係のみがあります。

「所有側」という名前の理由は何ですか?

Hibernateによって追跡されるリレーションの所有側は、データベースで外部キーを所有するリレーションの側です。

所有側の概念が解決する問題は何ですか?

所有側宣言せずにマップされた2つのエンティティの例を見てみましょう。

@Entity
@Table(name="PERSONS")
public class Person {
    @OneToMany
    private List<IdDocument>  idDocuments;
}

@Entity
@Table(name="ID_DOCUMENTS")
public class IdDocument {
    @ManyToOne
    private Person person;
}

OOの観点からは、このマッピングは1つの双方向の関係ではなく、2つの別々の単方向の関係を定義します。

マッピングはテーブルPERSONSとを作成するだけでなくID_DOCUMENTS、3番目の関連テーブルも作成しますPERSONS_ID_DOCUMENTS

CREATE TABLE PERSONS_ID_DOCUMENTS
(
  persons_id bigint NOT NULL,
  id_documents_id bigint NOT NULL,
  CONSTRAINT fk_persons FOREIGN KEY (persons_id) REFERENCES persons (id),
  CONSTRAINT fk_docs FOREIGN KEY (id_documents_id) REFERENCES id_documents (id),
  CONSTRAINT pk UNIQUE (id_documents_id)
)

主キーのみがpkオンになっていることに注意してくださいID_DOCUMENTS。この場合、Hibernateはリレーションの両側を個別に追跡しPerson.idDocumentsますPERSON_ID_DOCUMENTS。ドキュメントをリレーションに追加すると、関連付けテーブルにレコードが挿入されます。

一方、を呼び出すとidDocument.setPerson(person)、テーブルの外部キーperson_idが変更されますID_DOCUMENTS。Hibernateは、1つの双方向オブジェクトリレーションを実装するために、データベース上に2つの単方向(外部キー)リレーションを作成しています。

所有側の概念が問題を解決する方法:

私たちが望むものを何度だけ、テーブルの外部キーであるID_DOCUMENTSに向けてPERSONS、余分なアソシエーションテーブル。

これを解決するには、リレーションの変更の追跡を停止するようにHibernateを構成する必要がありますPerson.idDocuments。Hibernateはリレーションの反対側のみを追跡する必要IdDocument.personがあります。そのためには、mapedByを追加します

@OneToMany(mappedBy="person")
private List<IdDocument>  idDocuments;

mapsByはどういう意味ですか?

つまり、「リレーションのこちら側の変更 は、リレーションIdDocument.personのもう一方の側ですでにマップされているため、ここで個別に追加のテーブルで追跡する必要はありません。」

GOTCHA、結果はありますか?

mappedByを使用すると、を呼び出すだけの場合person.getDocuments().add(document)、外部キーin ID_DOCUMENTSは新しいドキュメントにリンクされません。これは、関係の所有/追跡された側ではないためです。

新しい人に文書をリンクするには、明示的に呼び出す必要があるdocument.setPerson(person)ことがあるので、所有側関係の。

mappedByを使用する場合、データベース内の新しいリレーションの永続化をトリガーするために、所有する側を把握し、リレーションの正しい側を更新するのは開発者の責任です。


17
Doctrineの 'mappedBy' + 'inversedBy'について説明している最良の答えです。
Kurt Zhong、2014

1
マッピングとコンセプトの背後にある理由を指定していただきありがとうございます。
モニッシュ、2016

1
変更されたかどうかはわかりませんが、Hibernate 5.0.9.Final person.getDocuments().add(document)で「呼び出すだけ」の場合、Hibernate は外部キーを更新しますID_DOCUMENTS
K.Nicholas

1
@Karl Nicholasさん、こんにちは@OneToMany。PERSISTに設定できるアノテーションにカスケード属性があることに同意します。この場合、HibernateはリンクされたすべてのエンティティをDBに保存します。誰かがこれを明確にしてもらえますか-なぜ著者はhibernateが所有していない側の変更を追跡しないと言いますが、実際にはhibernatedが追跡を実行するのですか?
Oleksandr Papchenko 2017年

3
カスケードは、親エンティティが子エンティティを所有していない場合でも子エンティティを保存するようプロバイダーに指示するため、ルールを効果的に変更します。mappedBy = child.fieldがあり(または持っていて)、カスケードがなかった場合、リストの子は保存されません。また、mapedByがなく、かつカスケードがなかった場合は、親が関係を所有し、新しい子をリストに入れて親を保存すると、新しい子IDを使用できないため例外がスローされます。結合テーブルに保存されます。物事が明確になることを願っています... :)
K.Nicholas

142

所有する側が他のへの参照を持つエンティティであると想像できます。抜粋では、1対1の関係にあります。それは対称的な関係であるため、オブジェクトAがオブジェクトBと関係している場合、その逆も真になります。

これは、オブジェクトAへの参照をオブジェクトBに保存し、オブジェクトBにオブジェクトAへの参照を保存することは冗長であることを意味します。そのため、参照を持つ他のオブジェクトを「所有する」オブジェクトを選択します。

1対多の関係がある場合、「多」の部分に関連するオブジェクトが所有側になります。それ以外の場合は、単一のオブジェクトから多数への参照を多数格納する必要があります。これを回避するために、2番目のクラスのすべてのオブジェクトには、参照する単一のオブジェクトへのポインタがあります(したがって、それらは所有側です)。

多対多の関係では、とにかく個別のマッピングテーブルが必要になるため、所有する側はありません。

結論として、所有する側は、他のものへの参照を持つエンティティです。


6
ご説明ありがとうございます。
学習者のみ2010年

2
それは、私たちが所有側を定義しないとどうなるか、なども怒鳴る私の名前「mappedBy」の理由のための答えと「所有する側」を参照するのに役立ち落とし穴、それが役に立てば幸いかもしれない
角度大学

5
まあ、答えはほぼ正しいと思います。しかし、少なくともHibernateの場合、多対多の関係でさえ所有する側面があります。これは、たとえば更新動作に影響を与えます。このチュートリアルのセクション4(「更新休止モデルクラス」)をよく見ておいてください。viralpatel.net/blogs/...を
Pfiver

11
この答えは、助けになる以上に混乱します。双方向の関係で、両方のEntityオブジェクトが相互に参照を持つ場合、「所有する側がもう一方への参照を持つエンティティであると想像できます」と言ってもいいのでしょうか。また、「多対多の関係の場合は、とにかく所有側が存在しないため、別個のマッピングテーブルが必要になる」というのは、まったく間違っ@ManyToManyています。関係にも所有側があります。同様に、@OneToMany関係は結合テーブルを使用できますが、所有側を指定する必要があります。
DavidS 2015

5
基本的に、これは真実よりも理解しやすいため、賛成票を持つかわいい、気持ちの良い答えです。
DavidS 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.