web-dev-qa-db-ja.com

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

所有側とはどういう意味ですか?マッピングの例(1対多、1対1、多対1)の説明は何ですか?

次のテキストは、@ OneToOne in Java EE 6の説明からの抜粋ですドキュメンテーション。コンセプトowning sideを見ることができます。

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

114
Just a learner

所有側は、もう一方への参照を持つエンティティであると想像できます。抜粋では、1対1の関係があります。それはsymmetric関係なので、オブジェクトAがオブジェクトBと関係している場合、その逆も成り立ちます。

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

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

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

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

133
Jack

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

双方向リレーションの所有側の概念は、リレーショナルデータベースにはオブジェクトの場合のような双方向リレーションが存在しないという事実に基づいています。データベースには、一方向の関係(外部キー)しかありません。

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

Hibernateによって追跡される関係の所有側は、データベース内の外部キーをownsする関係の側です。

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

所有側を宣言するwithoutでマッピングされた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つの双方向リレーションではなく、two個別の単方向リレーションを定義します。

マッピングは、テーブル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)
)
_

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

一方、idDocument.setPerson(person)を呼び出すと、テーブル_ID_DOCUMENTS_の外部キーperson_idを変更します。 Hibernateは、データベースにtwo単方向(外部キー)リレーションを作成し、one双方向オブジェクトリレーションを実装しています。

所有側の概念がどのように問題を解決するか:

多くの場合、必要なのは、PERSONSに対するテーブル_ID_DOCUMENTS_の外部キーと追加の関連テーブルだけです。

これを解決するには、リレーション_Person.idDocuments_の変更の追跡を停止するようにHibernateを構成する必要があります。 Hibernateは、リレーション_IdDocument.person_のother側のみを追跡する必要があります。そうするために、mappedByを追加します。

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

mappedByとはどういう意味ですか?

これは次のようなことを意味します。「リレーションのこちら側の変更はすでにリレーションIdDocument.personの反対側Mapped Byであるため、ここで追加のテーブルで個別に追跡する必要はありません。 」

GOTCHA、結果はありますか?

mappedByを使用して、person.getDocuments().add(document)を呼び出すだけの場合、_ID_DOCUMENTS_の外部キーは[〜#〜] not [〜#〜 ]は、新しいドキュメントにリンクされます。これは、リレーションの所有/追跡された側ではないためです!

ドキュメントを新しい人にリンクするには、document.setPerson(person)を明示的に呼び出す必要があります。これは、所有側であるためです関係の。

mappedByを使用する場合、開発者は所有側を把握し、データベースの新しいリレーションの永続性をトリガーするためにリレーションの正しいサイドを更新する必要があります。

163