[play1-jpa]テーブル間の関係記述

  playframework1

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

LEAVE A COMMENT