付録C.1 ランタイムに関する規約
ランタイムに関する規約には,コンテナ側の責任とJPAプロバイダ側の責任があります。
- 〈この項の構成〉
(1) コンテナ側の責任
-
トランザクションスコープの永続化コンテキストに関する規約
トランザクションスコープの永続化コンテキストが使用されている場合に,JTAトランザクションにエンティティマネージャが関連づいていないときには,コンテナは次の処理を実行します。
-
コンテナは次の場合に,EntityManagerFactory.createEntityManagerを呼び出して新しいエンティティマネージャを作成します。
JTAトランザクションのスコープ内のビジネスメソッドで,トランザクションスコープの永続化コンテキストを使用するエンティティマネージャのメソッドが初めて呼び出された場合
-
JTAトランザクションが決着(コミットまたはロールバック)したあとに,コンテナはEntityManager.closeを呼び出して,エンティティマネージャをクローズします。
また,コンテナは次の条件をすべて満たすと,TransactionRequiredExceptionをスローします。
-
トランザクションスコープの永続化コンテキストが使用されている場合
-
トランザクションがアクティブでない場合
-
アプリケーションからEntityManagerのpersist,remove,merge,refreshメソッドが呼び出された場合
-
-
拡張永続化コンテキストに関する規約
拡張永続化コンテキストが使用されている場合は,コンテナは次の処理を行います。
-
コンテナは次の場合に,EntityManagerFactory.createEntityManagerを呼び出して新しいエンティティマネージャを作成します。
Stateful Session Beanのインスタンスが作成された際に,拡張永続化コンテキストを使用するエンティティマネージャへの参照が定義されている場合
-
コンテナは次のタイミングで,EntityManager.closeを呼び出してエンティティマネージャをクローズします。
エンティティマネージャを作成したStateful Session Bean,および同じ永続化コンテキストを引き継いだStateful Session Beanが削除されたとき
-
コンテナ管理のトランザクションを使用するStateful Session Beanのビジネスメソッドの呼び出し時に,エンティティマネージャがJTAトランザクションと関連づけられていない場合には,コンテナはエンティティマネージャをJTAトランザクションに関連づけ,EntityManager.joinTransactionを呼び出します。JTAトランザクションにすでに別のエンティティマネージャが関連づけられている場合には,コンテナはEJBExceptionをスローします。
-
ビーン管理のトランザクションを使用するStateful Session Beanのビジネスメソッド内でUserTransaction.beginが呼び出された場合には,コンテナはエンティティマネージャをJTAトランザクションと関連づけ,EntityManager.joinTransactionを呼び出します。なお,ビーン管理のトランザクションについては,マニュアル「アプリケーションサーバ 機能解説 基本・開発編(EJBコンテナ)」の「2.7.2 BMT」を参照してください。
-
-
コンテナ管理のエンティティマネージャに関する規約
コンテナ管理のエンティティマネージャを使用している場合に,アプリケーションがEntityManager.closeを呼び出すと,コンテナはIllegalStateExceptionをスローします。
@PersistenceCotnextまたはDDの<persistence-context-ref>タグで,プロパティが指定された場合には,コンテナはEntityManagerFactory.createEntityManager(Map map)メソッドを使用してエンティティマネージャを作成し,指定されたプロパティをmap引数に含めてJPAプロバイダに渡します。
-
コネクションの自動クローズ機能について
アプリケーションサーバの場合,Session BeanやWebコンポーネントの延長でJPAプロバイダが取得したコネクションは,コンテナの自動クローズ機能によって自動的にクローズされることがあります。コネクションの自動クローズ機能とは,コネクションのリークを防止するための機能です。
コネクションは,次の条件を満たすと自動クローズの対象となります。
-
Stateless Session Beanで取得したコネクションは,ビジネスメソッドからリターンするときに,自動クローズの対象となります。
-
Stateful Session Beanで取得したコネクションは,Stateful Session Beanが破棄されるときに,自動クローズの対象となります。
-
Webコンポーネントで取得したコネクションは,サービスメソッドからリターンするときに,自動クローズの対象となります。
ただし,これらの条件に当てはまる場合でも,コネクションがJTAトランザクションに参加しているときには,JTAトランザクションがコミットするまで自動クローズが保留されます。
-
(2) JPAプロバイダ側の責任
アプリケーションで使用するエンティティマネージャが,トランザクションスコープの永続化コンテキストを使用するように定義されているか,拡張永続化コンテキストを使用するように定義されているかは,JPAプロバイダには伝わりません。JPAプロバイダでの責任は,コンテナが要求したときにエンティティマネージャを作成し,トランザクションからトランザクションの決着の通知を受け取るためのSynchronizationをトランザクションに登録することです。
-
コンテナがEntityManagerFactory.createEntityManagerを呼び出したときには,JPAプロバイダは新しいエンティティマネージャを作成し,それをコンテナに返す必要があります。JTAトランザクションがアクティブである場合は,JPAプロバイダはSynchronizationをJTAトランザクションに登録する必要があります。
-
コンテナがEntityManager.joinTransactionを呼び出したときには,JPAプロバイダはSynchronizationをJTAトランザクションに登録する必要があります。ただし,以前にjoinTransactionが呼び出されていて,JTAトランザクションにSynchronizationを登録済みの場合には,何もする必要はありません。
-
JTAトランザクションがコミットされるときには,JPAプロバイダはすべての変更されたエンティティの状態を,データベースにフラッシュする必要があります。
-
JTAトランザクションがロールバックされるときには,JPAプロバイダは,すべてのmanaged状態のエンティティをdetached状態にする必要があります。
-
JPAプロバイダがトランザクションのロールバックの原因になる例外をスローする場合には,JPAプロバイダがトランザクションをロールバックにマークする必要があります。
-
コンテナがEntityManager.closeを呼び出した場合,そのエンティティマネージャが関係したすべての未解決トランザクションが決着されたあとに,JPAプロバイダはすべての確保したリソースを解放する必要があります。エンティティマネージャがすでにクローズされている場合には,JPAプロバイダはIllegalStateExceptionをスローする必要があります。
-
コンテナがEntityManager.clearを呼び出した場合,JPAプロバイダはすべてのmanaged状態のエンティティをdetached状態にする必要があります。
(3) javax.transaction.TransactionSynchronizationRegistryインタフェース
JPAプロバイダは,トランザクションにSynchronizationを登録したり,トランザクションをロールバックにマークしたりするために,TransactionSynchronizationRegistryインタフェースを使用できます。TransactionSynchronizationRegistryのインスタンスは,JNDIを使用して「java:comp/TransactionSynchronizationRegistry」という名前でルックアップできます。
インタフェース定義は標準仕様書を参照してください。