関係性ペア

通常、@OneToMany@ManyToOneは関係性の両側面を表すペアとして利用できます。そのため、@OneToManyは関係性の「多」側の側面を持ち、@ManyToOneは関係性の「一」側の側面を持ちます。

mappedBy

mappedBy属性は、ほとんどの@OneToManyで定義する必要があります。mappedBy属性は、実質的には関係性のもう一方の側面を参照します。

例: 顧客には多くの連絡先があります

@Entity
public class Customer ...

  // mappedBy referring to the other side of this relationship
  @OneToMany(mappedBy="customer")
  List<Contact> contacts;
  ...

ContactエンティティBeanの関係性のもう一方の側面では、mappedByが参照する@ManyToOneプロパティを定義します。

@Entity
public class Contact ...

  // the customer property referred to by @OneToMany(mappedBy="customer")
  @ManyToOne(optional=false)
  Customer customer;
  ...

双方向

@OneToMany@ManyToOneのペアで関係性の両方の側面をマッピングする場合は、これを双方向関係と表現できます。この関係性は、どちらの方向からも表示、ナビゲート、読み込むことができます。

双方向関係には制限はありません。

@OneToManyのマッピングなし

関係性の@OneToMany側をマッピングしないことを選択するのは、主数が大きい場合(たとえば数千)で、その方向に関係性をナビゲートすることをアプリケーションに許可したくないと判断した場合です。これを単純に行うと、あまりにも多くのオブジェクトが読み込まれる可能性があるためです。

たとえば、顧客に100万件の注文があり、その顧客からすべての注文に対して単純にナビゲートした場合、100万件の注文インスタンスがメモリに読み込まれる可能性があります。これは一般的に望まない動作です。この場合、顧客のクエリでfilterManyを使用し、それぞれの顧客の注文をフィルタリングできます(たとえば、先週に作成された注文など)。あるいは、グラフィックを逆方向(注文から顧客)に読み込むこともできます。

@OneToManyを省略すると、その方向から関係性をナビゲートまたは読み込むことができなくなり、代わりにアプリケーションは常に別の方向を使用するようになります(オブジェクトグラフィックを構築するために)。

@ManyToOneのマッピングなし

@ManyToOneをマッピングしないと、制限が追加され、所有関係が暗黙的に示されます。

たとえば、注文に複数の注文詳細がある場合、OrderDetailで@ManyToOne側をマッピングしない場合

注文には詳細がある

@Entity
@Table(name = "orders")
public class Order ...

  // we MUST have cascade persist here for this
  // unidirectional case (no @ManyToOne)
  @OneToMany(cascade = CascadeType.ALL)
  List<OrderDetail> details;
  ...

OrderDetailには一致する@ManyToOneがない

@Entity
public class OrderDetail ...

  // Does not have - @ManyToOne(optional = false) Order order;

その結果、新しい OrderDetails を挿入するには、cascade が Order から継承されるという制約が追加されます。つまり、@ManyToOne は、OrderDetail の下にあるテーブル上の外部キーを表し、その外部キーを指定する必要があります。そのため、cascade を Order から継承する必要があります

これはまた、外部キーの値は決して変更できず、したがって理論的には所有権の関係として見ることができるということを示唆しています。この例では、各 OrderDetail は Order によって「所有」されています。

私はいつも @ManyToOne をマッピングしています