jpaの機能ですが、playframework1の場合はgetter/setter不要なこともあり一般的なサンプルと少し記述が違います。
1:n
自分1レコードに対し、子nレコードの場合は、@OneToMany
アノテーションを使う。
子エンティティを参照するためのコレクション型のプロパティを設け、このプロパティへのアクセスが子エンティティへのアクセスとなる。
public class Parent {
@OneToMany(mappedBy = "parent")
public List<Child> children;
}
mappedBy
を省略すると、Parent
テーブルとChild
テーブルの関係を保持するための中間テーブルが自動で作成される。mappedBy
で子クラスの親参照プロパティを指定すると、中間テーブルは作られない。
(中間テーブルは、通常 n:n の場合に必要に迫られて作る感覚だったので、省略すると中間テーブルが作られるのはちょっと違和感あり。)
逆に子クラスが親クラスを参照する時は、@ManyToOne
アノテーションを使う。
親エンティティを参照するためのプロパティを設け、このプロパティへのアクセスが親エンティティへのアクセスとなる。
public class Child {
@ManyToOne
public Parent parent;
}
順序
関係性を記述してコレクション型のプロパティを設けたとき、@OrderBy
アノテーションによりその要素の順序を指定することができる。
@ManyToMany
@OrderBy("lastname ASC", "seniority DESC")
public List<Employee> getEmployees() {
...
};
応用してソート条件ごとにコレクション型プロパティを設けることもできる。(名前降順で取得したいときのプロパティ、年齢昇順で取得したいときのプロパティ、のように)
orphanRemoval
親子関係のあるエンティティに対して、JPA2の新機能であるorphanRemoval
の機能を使うことで単に親のコレクションから削除するだけで、関連付けが削除されると同時に子エンティティ自身もDELETEされる。
子エンティティの数だけDELETEが発行されるようなので、パフォーマンスを求めるなら自前で条件を書いてDELETEした方が良いかもしれない。
CascadeType.REMOVE, orphanRemoval=true
にして関連エンティティの削除を自動で行わせようとするとき、参照整合性制約エラーが発生することがある。このようなときは関連エンティティを先に削除する処理を自前で記述しなければいけなさそう。検証が必要。
子を全て削除
子Objのdelete()メソッドを呼びまくる。⇒DELETEが子Objの数だけ発行される。良くない。
子Objを親IDで絞り込んで Child.delete("parent = ?", parent);
で削除すると DELETEは1回で済む。
親Objへ削除を反映させる為に、親Obj.reflesh()
しておきたい。
参考
今からでも遅くない JPAを学ぼう!(後編) オブジェクト間の関連を理解し、JPQLを使用する (1/6):CodeZine(コードジン)
https://codezine.jp/article/detail/5061