はじめに
JPAを使うときの指針メモです。
JPQLではなくCriteriaを使う
SQLを知っているとJPQLの方がとっつきやすいのですが、以下の理由からCriteriaを使ったほうがよさそうです。
CriteriaはDB変更に強い
JPQLはタイプセーフではないので、Entityクラス名や変数名が変わってもコンパイルエラーになりません。
対応箇所は自分で洗い出すか、動かしてエラーになるまでわかりません。
一方Criteriaは、Entityを変更した時点でコンパイルエラーになるので対応箇所がすぐにわかります。
JPQLをデバックするのは大変
SQLと違ってDBのコンソールで試すことが出来ないので、SQLの感覚で長いJPQLを書いてエラーになったらデバックするのがかなり大変です。
エラーメッセージとにらめっこする羽目になります。
コード例
// nameが"aaa aaa"のデータを検索
List<User> users = User.find("name", "aaa aaa").fetch();
// nameが"aaa aaa"のデータを検索
Session session = (Session) JPA.em().getDelegate();
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.eq("name", "aaa aaa"));
List<User> users = criteria.list();
※サンプルコードはPlayFramework1.2系のものです。参考程度に見ていただき、実際の書き方は各FWのサイト等でご確認ください。
JPAからいきなりDTO(画面に表示するためのオブジェクト)にマッピングしようとしない
クエリの結果は単項目かEntityオブジェクトの形で受け取るのが普通です。
複数のEntityから任意の項目を取得したい場合、JPAでは単純なクエリを投げて、結果をEntityとして取得します。
複数Entityの情報が必要な場合は複数回クエリを投げて、ビジネスロジックでオブジェクトを操作してDTOに詰め直します。
慣れるまではSQLで書けば一発なのにムキー!となりますね。