Java における ManyToOne
関係とは、ソース オブジェクトが別のオブジェクト、ターゲット オブジェクトを参照する属性を持っている場合です。 すなわち、1 つのオブジェクトが別のオブジェクトへの参照を保持するという、むしろ典型的な Java のケースです。 ManyToOne
関係は、一方向に指定することができる。 しかし、ターゲット・オブジェクトはソース・オブジェクトに戻る逆方向の関係を指定することが一般的です。 これは、ターゲットオブジェクトにOneToMany
リレーションシップを指定することになる。 つまり、ソースオブジェクトがターゲットオブジェクトを参照しても、ターゲットオブジェクトがソースオブジェクトとリレーションを持つ保証はありません。 これは、外部キーとクエリによって関係が定義され、逆クエリが常に存在するようなリレーショナルデータベースとは異なります。
JPAではManyToOne
関係は@ManyToOne
アノテーションまたは<many-to-one>
要素で指定されます。 @ManyToOne
アノテーションは通常@JoinColumn
アノテーションを伴います。 @JoinColumn
アノテーションは、関係がどのようにデータベースにマッピングされるか(表現されるか)を指定する。 @JoinColumn
は、ターゲット・オブジェクトを見つける(結合する)ために使用されるべき、ソース・オブジェクトの外部キー列(@JoinColumn(name = "...")
)の名前を定義します。
逆OneToMany
関係がターゲット・オブジェクトに指定されている場合、ターゲット・オブジェクトの@OneToMany
アノテーションには、この逆関係を定義するmappedBy
属性が含まれていなければなりません。
JPAはOneToOne
関係も定義しており、これはManyToOne
関係に似ているが、逆関係が(もし定義されていれば)OneToOne
関係であることを除いては、ManyToOne
関係と同じである。 JPAにおけるOneToOne
とManyToOne
の関係の主な違いは、ManyToOne
は常にソースオブジェクトのテーブルからターゲットオブジェクトのテーブルへの外部キーを含むのに対し、OneToOne
関係では外部キーはソースオブジェクトのテーブルにもターゲットオブジェクトのテーブルにもあり得るということです。
ManyToOne関係の例 databaseEdit
EMPLOYEE (table)
EMP_ID | FIRSTNAME | ||||||||||||||||||||||||||||||||
FIRSTNAME |
SALARY | MANAGER_ID | |||
1 | Bob | Way | 50000 | 2 |
2 | Sarah | Smith | 75000 | null |
PHONE (table)
ID | TYPE | AREA_CODE | P_NUMBER | OWNER_ID | |
1 | home | 613 | 792-> | 7920000 | 1 |
2 | work | 613 | 896-…1234 | 1 | |
3 | work | 416 | 123-…4444 | 2 |
ManyToOne関係の例 annotationsEdit
@Entitypublic class Phone { @Id private long id; ... // Specifies the PHONE table does not contain an owner column, but // an OWNER_ID column with a foreign key. And creates a join to // lazily fetch the owner @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="OWNER_ID") private Employee owner; ...}// Specification of the reverse OneToMany relationship in Employee@Entitypublic class Employee { @Id private long emp_id; ... // The 'mappedBy = "owner"' attribute specifies that // the 'private Employee owner;' field in Phone owns the // relationship (i.e. contains the foreign key for the query to // find all phones for an employee.) @OneToMany(mappedBy = "owner") private List<Phone> phones; ...
ManyToOneの例 リレーションシップ XMLEdit
<entity name="Phone" class="org.acme.Phone" access="FIELD"> <attributes> <id name="id"/> <many-to-one name="owner" fetch="LAZY"> <join-column name="OWNER_ID"/> </many-to-one> </attributes></entity>
See AlsoEdit
- Relationships
- Cascading
- Lazy Fetching
- 対象エンティティ
- 結合フェッチ
- 一括読み込み
- 共通の問題
- OneToOne
- Mapping a Pasting of a Entity
- Batch Reading
- Batch Reading
- Mapping a Entity
- OneToOne
- OneToMany
Mapping a Entity
Common ProblemsEdit
外部キーは主キーの一部でもあります。編集
OneToOne関係による主キーを参照してください。
外部キーは基本キーとしてもマッピングされます。 編集
2つの異なるマッピングで同じフィールドを使用する場合、通常、
insertable, updatable = false
を使用してそのうちの1つを読み取り専用にする必要があります。 ターゲット外部キー、プライマリキー結合列、カスケードプライマリキーを参照してください。挿入時の制約エラー
これは通常、
OneToOne
リレーションシップの外部キーのマッピングが正しくないために発生します。 また、JPAプロバイダが参照整合性をサポートしていない場合や、双方向制約を解決しない場合にも発生することがあります。 この場合、制約を削除するか、EntityManager
flush()
を使用してオブジェクトの記述順序を確認する必要があります。外部キー値がヌルです。
オブジェクトの
OneToOne
値を設定することを確認してください。OneToOne
が双方向のOneToMany
リレーションの一部である場合、OneToMany
にオブジェクトを追加するときにオブジェクトのOneToOne
を設定することを確認してください。 また、JoinColumn
を正しく定義しているか、insertable, updateable = false
を設定していないか、PrimaryKeyJoinColumn
を使用していないかも確認します。