2012-01-15 26 views
1

EntityMangerには、@PersistenceContext注釈が挿入されています。これは私の "DAO/Repository"クラスのメソッドであり、アノテーションは付けられていません。このクラスは、データベースとの間でデータを取得する必要があるEJBに注入されます。EntityManager.persist()の後の処理

これまでは、以下のpersistメソッドの終了後にpersistencecontextがフラッシュされ、データがデータベースに格納されていたと思っていましたが、私のアプリで何が起きているのか疑い始めました。私はGlassfishでデータソースと接続プールを作っていますので、コンテナ管理のトランザクションを使用していますが、トランザクションの注釈は使用していません。

誰かが私のためにいくつかの光を投げることができますか?

public void persist(QuestionFeedback questionFeedback) { 
    questionFeedback.setCreated(new Date()); 
    entityManager.persist(questionFeedback); 
} 

Glassfishの3を使用するには、JavaのEE6 compatiblity

答えて

0

あなたが任意のトランザクションを使用しない場合は、デフォルトのトランザクションが必要とされる注釈します。したがって、DAOはトランザクションで実行され、トランザクションがコミットされたときよりも永続コンテキストが後でフラッシュされなくなります。 JavaDocのから

TransactionAttribute上:

TransactionAttributeアノテーションが指定されていない場合

、およびBeanがコンテナ管理によるトランザクションの境界設定を使用して、REQUIREDトランザクション属性のセマンティクスを想定しています。 FlushModeTypeに対してjavadocから

FlushModeType.AUTOは、クエリまたはTypedQueryオブジェクトに設定されている場合、または永続コンテキストのフラッシュモードの設定がある場合、クエリは、トランザクション内で実行されていますAUTO(デフォルト)およびフラッシュモード設定がQueryまたはTypedQueryオブジェクトに指定されていない場合、永続性プロバイダは、永続コンテキスト内のすべてのエンティティの状態に対するすべての更新がクエリの結果に影響を与える可能性があることを確認します照会の処理で可視です。

これは、その結果がそのフラッシュによって影響を受けるクエリを使用すると、永続コンテキストが先にフラッシュされる可能性があることを意味します。

3

persist方法は、企業が永続的になりますが、まだデータベースに変更を書き込みません。これは通常、トランザクションがコミットするときに発生します(プロバイダーはこれを最適化することは自由です。以前に発生する書き込みを強制することができますが、それはまだ、現在のトランザクションに参加するコードに表示されますflush

。書き込みを永久に(すべての外部コードから参照できるように)するには、依然としてトランザクションをコミットする必要があります。

アノテーションを明示的に指定しないと、EJB Beanはデフォルトでトランザクションになります。

0

のEntityManagerは@PersistenceContextアノテーションを介して注入されているので、あなたは、コンテナ管理トランザクションを使用したことを確認するためのものです。

とにかく、永続性がトランザクションコミットを引き起こすという前提は間違っています。 commitを介して実行された変更はコミット中のデータベースに対して行われます。 EntityManagerのドキュメントによれば、「新しいインスタンスは、persistを呼び出すことによって管理され永続化されます。このコンテキストでは、「存続する」とは、その時点でエンティティがデータベースに保持されているわけではありません。 persistが呼び出された瞬間、エンティティはPersistenceContextの用語で永続化されます。トランザクションがコミットすると、後でデータベースに最新の状態に保持されます。

あなたのメソッドに@TransactionAttributeアノテーションを使用していないので、デフォルトが適用されます。デフォルトはTransactionAttributeType.REQUIREDです。これにより、コンテナは最初のビジネスメソッドが呼び出されたときにトランザクションを作成し、これを他のメソッドに伝播させます。最初のビジネスメソッドへの呼び出しが完了すると、トランザクションがコミットされます。その後、変更内容はデータベースに格納されます(ロールバックが実行されていない場合)。

+0

これは、ビジネスメソッドがトランザクション(私のコードで上記のpersistメソッドを呼び出すメソッド)を開き、閉じた後、トランザクションがコミットされるということですか?それとも私はあなたを誤解していますか? – LuckyLuke

+0

はい、persistメソッドを呼び出すメソッドのクライアントにトランザクションコンテキストがない場合。そして、あなたのケースでは、コンテナは、メソッドの開始と終了でトランザクションの開始とコミットに注意を払わなければなりません。クライアントが既存のトランザクションを持っていれば、あなたのメソッドはそれに結合し、クライアントのどこかでコミットが行われます。トランザクションの属性が定義されていないこれらのメソッド呼び出しのレイヤ数は関係ありませんが、ロジックは同じです。トランザクションは最初のトランザクションで開始され、コミットされます。 –

関連する問題