JPA Hibernateの使いどころ
ブログのキーワード等で色々な人の考えを読んだ限りでは、Hibernateは複雑で使いにくいという人が多いし、JPAは微妙だと言う人が多いと感じています。それは間違いではないと思います。SQLを発行したいという目的に対しては、JPA・Hibernateは複雑すぎますし、SQLベースのORMに比べてSQL実行処理が使い易いわけではありません(特にJPAのSQLの使い辛さは致命的です)。CRUD処理ではSQLをほぼ自動発行できますが、そのレベルの処理ならば、今はどのORMも標準機能として持っています。
ではこれらのFWは要らないものなのでしょうか? 自分はたまたま仕事上でHibernateを複数回使い、その特長が最近になってようやく解ってきました。たしかに複雑で、初心者にとって敷居の高いFWです。Entityの状態変更とかLAZYロードとか、よく解ってないとすぐにハマってしまいます。
でもその一方で、ERモデルのマッピング標準としてはかなり優れていると感じています。特にERの関連をJavaオブジェクトとして明示化するにはピッタリな規格です。S2JDBCがマッピング部分にJPAのクラスを利用しているのも、そのことを裏付けているのではないかと思います。
この「ERモデルの関連を明示化する」ことが、JPA・Hibernateの最大の特長ではないかと感じています。その為のLAZYロードでありJPQLによるJOINの省略記述です。ER設計時にこのEntityの関連を厳密に定義し、外部キー制約等を含めてJPA・Hibernateの規約に合うような設計を行えば、JPA・Hibernateの利便度は確実に上がると感じています。逆にこの部分を厳密に定義しない場合(外部キーが厳密な外部キーでない、結合条件にロジックが必要、主キーが無い等)、SQLの結果セットではなくERモデルそのものを基盤とするJPA・Hibernateは非常に使い辛い代物に成り果てます。外部キーをキーにLAZYロードを行い、関連Entityが取れなかったらエラーになるのがHibernateの標準の動きなので、そもそも外部キー制約が適用できないような関連には上手く当てはまりません(例外を抑えるオプションもあるにはありますが)。
これは、そういうテーブル定義がいけないと言っているのではなく、JPA・HibernateはそういうDB設計を前提にしているということを利用者は知っておくべきだということです。RailsのActiveRecordを使う場合、DBはRails用の規約で固めることが前提になると思いますが、それと非常に似ています。
JPA・Hibernateの問題点は、そういう現実をあまり主張せず「RDBを隠蔽してオブジェクトによる永続化処理を行う」と宣伝してしまっていることだと思います。それは間違いではありませんが、「RDBを隠蔽できる」=「利用するDBがどのような状態であっても、そのDB設計に依存せずにORMだけを見て処理が出来る」ことではありません。真にRDBからの依存をなくしてObjectによる処理を行いたければ、まずはJPA・Hibernate利用を前提としたDB設計を行い、JPA・HibernateによるERモデルのマッピングを完璧に理解し、その上でEntityに対して継承戦略・クラス組み込みなどRDBの概念に無いクラス定義を加えていく形になります。そこは利用者が行わなければなりません。JPA・Hibernateはただ単にカスタマイズの為の各機能を提供しているだけです。基本はERモデルであり、JPA・Hibernate共に標準の状態ではRDBを隠蔽するのではなく、むしろERモデルを全面に出して明示化します。このことを理解せず、誤った認識でこれらのFWを使うと、利用効果は望めないと思います。
逆に考えれば、RDBを隠蔽するつもりが無い場合でも、ERモデル(特にその関連定義)を重要視するのであれば、JPA・Hibernateを検討する価値はあると思います。どちらにせよ、現状のシステム開発ではRDBを無視した開発は出来ませんし、ER設計は軽視できません。それならば、ER設計に力を入れて、その成果を直接JPA・Hibernateによりマッピングし、Javaから明示的に利用する・・・このような目的であれば、これらのFWはその力を発揮できるのではないかと感じています。
JPA・Hibernateを使う場合はER設計が重要、ER設計の成果を前提に永続化処理を効率的に行いたい場合、JPA・Hibernateは有効、今はこう考えています。