HQL と outer-join 属性

某巨大掲示板に反応して久々に Hibernate ネタ.
HQL を使った問い合わせで,明示的に結合するのは面倒くさいということですが,明示的に書くしかありませんから!! 残念!!!!
関連のマッピング定義に outer-join 属性を指定すれば,と読めそうな意見もありますが,Criteria を使った場合には有効なものの,Session#find() など,HQL を使った問い合わせには関係ありません.


ということが,「Hibernate in Action (isbn:193239415x)」にバッチリ明記されています.P261 から引用.

HQL always ignores the mapping document eager fetch (outer join) setting. If you've mapped some associations to be fetched by outer join (by setting outer-join="true" on the association mapping), any HQL query will ignore this preference. You must use an explicit fetch join if you want eager fetching in HQL.
(中略)
HQL is designed to be as flexible as possible: You can completely (re)define the fetching strategy that should be used at runtime.


そんなわけで (どんなわけで?),どうしても SQL 一発で深ーく結合した結果を HQL で取得したければ,明示的に結合を記述するしかありません.
いやなら Criteria を使うか,SQL が複数回発行される可能性がありますが遅延ロードを使うかのどちらかになりますね.キャッシュが有効に使えるのであれば,遅延ロードに任せる方が Hibernate 的だと思います.
HQL を外部化しておくと,明示的に結合するのか一部を遅延ロードに任せるのかなどがマッピングファイルでチューニングできてよいのではないかと思います.


ついでに Hibernate 3 の話題.
パッケージが net.sf.hibernate から org.hibernate に変更になったのは知っていましたが,それ以外にも大きな変更がたくさんあるみたいですね.
例えば HibernateException は unchecked な実行時例外になりました.これで S2Hibernate として独自の Session インタフェースを提供する必要はなくなりますね.(^^;
その org.hibernate.Session からは,入門記でも散々使用してきた find() などがなくなってしまいました.(;_;)
HQL を使う場合には,常に createQuery() などで Query を作成しなければなりません.
これまでは,なんでもかんでも Session のメソッドを呼び出していたわけですが,少し整理しようという事みたいですね.
一応,org.hibernate.classic.Session というインタフェースが用意されていて,こちらには find() などが残されています.deprecated ですが.
って,いつの間にかベータになってるんだ... EJB3.0 (JSR-220) の EntityManager 風に create()merge() が導入されているんですね.
いつか「Hibernate3 入門記」しなきゃだめだったりして.
あう,その前に「JCA 入門記」を再開しないといけませんから!! よって,切腹!!!!


00:00 追記
あら? 3.0 のベータはまだですね.失礼しました.m(__)m
changelog に出ていた (でも日付は xx.x.2004) ので勘違いしてしまいました.切腹!!!!