Hibernate EntityManager 3.1 beta7

今回からHibernate3.2必須になりました。最も大きな変更は、やはりEntityManagerFactory.getEntityManagerメソッドが削除されたことでしょうか。トランザクションスコープのEntityManagerはHibernateでは提供されなくなったので、EJB3コンテナを利用するか、自前で実装する必要があります。とりあえず、JBoss EJB3の実装を参考に適当に作成して動かしてみました。
細かな部分では、継承戦略を使っているときに、DiscriminatorColumnが複合主キーの一部だとエラーになるようになりました。Hibernateの場合、このようなときはdiscriminatorタグのinsert属性をfalseにすることによって対応するのですが、JPAアノテーションで相当の処理をする方法を見つけることが出来ませんでした。とりあえず、Hibernate AnnotationsのDiscriminatorFormulaを利用することによって、エラーを回避しました。
あと、EntityManagerにgetDelegateメソッドが追加されました。Hibernateの場合、このメソッドによってSessionオブジェクトが取得出来ます。現在のJPA仕様はSQLを扱うときに非常に不便なので、自分はSQLを使うときにはこのメソッドを使ってSessionを取得して、HibernateAPIを利用しています。
もう一つ細かな修正として、EntityManagerFactoryが作成するEntityManagerは、トランザクションコミット時に自動的にflushしなくなりました。この修正によって、一時的に作成するEntityManagerを使用することがやり易くなりました。EventListener内でも安心して使えます。
(追記)またまた間違ってました(汗)・・・EntityManagerの内部のSessionについては、自動flush、close共に無効になりますが、EntityManagerについてはトランザクションコミット前に自動flushされます。ですから、EventListener等で使うときには、EntityManagerは色々と使いづらいので、SessionFactoryからSessionを取得して利用するのが良いみたいです。
あと、これはHibernate3.2の機能ですが、bytecodeツールをCGLIBとjavassistの2択で選べるようになりました。早速javassistを設定して使ってみたのですが、自分の環境ではあまり違いを感じられませんでした。
(追記)現在のバージョンでは、javassistを有効にするためには、システムプロパティかhibernate.propertiesに定義を書く必要があるみたいです。
Hibernate3.2では、fetch joinで1対多のコレクションと同時に1つのオブジェクトを取得した場合、これまではSQLの戻り値と同数のListが返ってきていたのが、オブジェクトレベルでDISTINCTされるようになったそうです。まだ試していませんが、これが出来るようになるとかなり便利になりそうな気がします。