Red Hat Training

A Red Hat training course is available for Red Hat JBoss Web Server

3.5. コンテキストのセッション

Hibernate を使用するアプリケーションの多くに、コンテキストの範囲全般を通じてセッションが有効になるある種の「コンテキスト」のセッションが必要となります。しかし、通常アプリケーションごとにコンテキストを構成するものの定義は異なります。さらに、コンテキストにより、定義する「現在」の概念の範囲が異なります。バージョン 3.0 以前の Hibernate を使用するアプリケーションは、自作の ThreadLocal ベースのコンテキストセッションや HibernateUtil などのヘルパークラス、プロキシやインターセプションベースのコンテキストセッションを提供した Spring や Pico などのサードパーティフレームワークを使用していました。
バージョン 3.0.1 より、Hibernate には SessionFactory.getCurrentSession() メソッドが加わりました。当初は、JTA トランザクションを使用し、JTA トランザクションが現在のセッションの範囲とコンテキストを両方定義することが前提となっていました。多くのスタンドアロン JTA TransactionManager 実装が成熟の段階に入っているため、J2EE コンテナへデプロイされるか否かに関わらずアプリケーションは JTA トランザクション管理を使用すべきです。これにより、使用する必要があるのは JTA ベースのコンテキストセッションのみとなります。
バージョン 3.1 より SessionFactory.getCurrentSession() 背後の処理がプラグ可能になりました。また、拡張インターフェース org.hibernate.context.CurrentSessionContext と設定パラメータ hibernate.current_session_context_class が新たに追加され、現在のセッションを定義する範囲とコンテキストがプラグ可能になりました。
org.hibernate.context.CurrentSessionContext インターフェースの詳細な規約については Javadoc を参照してください。このインターフェースは、実装が現在のコンテキストセッションの追跡に関与する単一のメソッド currentSession() を定義します。Hibernate には、このインターフェースの追加設定不要な 3 つの実装が含まれています。
  • org.hibernate.context.JTASessionContext: JTA トランザクションにより現在のセッションが追跡され、範囲が決定されます。この処理は、以前の JTA のみの方法と全く同じになります。詳細は Javadoc を参照してください。
  • org.hibernate.context.ThreadLocalSessionContext: 実行スレッドによって現在のセッションが追跡されます。詳細は Javadoc を参照してください。
  • org.hibernate.context.ManagedSessionContext: 実行スレッドによって現在のセッションが追跡されますが、ユーザーがこのクラス上の静的メソッドを用いて Session インスタンスをバインドまたはアンバインドしなければなりません。この実装は Session の開閉やフラッシュを行いません。
最初の 2 つの実装は、「1 セッション 1 データベーストランザクション」プログラミングモデルを提供します。これは リクエスト毎のセッション (session-per-request) とも呼ばれます。Hibernate セッションの開始と終了は、 データベーストランザクションの期間によって定義されます。 JTA を使用せず、 通常の JSE でプログラムを用いたトランザクション境界を使用する場合、Hibernate Transaction API を使用して基盤のトランザクションシステムをコードから見えないようにしてください。JTA を使用する場合、JTA インターフェースを使用してトランザクションの境界を設定することができます。CMT をサポートする EJB を実行する場合、トランザクション境界は宣言的に定義されるため、コードにトランザクションやセッションの境界を決定する操作は必要ありません。詳細やコード例は 12章トランザクションと並行性 を参照してください。
hibernate.current_session_context_class 設定パラメータは、org.hibernate.context.CurrentSessionContext のどの実装を使うべきかを指定します。下位互換性のため、このパラメータが設定されず org.hibernate.transaction.TransactionManagerLookup が設定されていた場合、Hibernate は org.hibernate.context.JTASessionContext を使うことに注意してください。通常このパラメータの値には利用する実装クラスを指定するだけです。しかし、カスタマイズなしに利用可能な実装3つについては、「jta」、「thread」、「managed」というそれぞれの省略名も用意されています。