0

私は、EXTENDED 永続コンテキストと次の @TransactionAttribute 設定を備えたステートフル セッション Bean を使用しています。

@Stateful(...)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class StatefulExtendedEJBBea {
    @PersistenceContext(unitName = "JPAModel", type = PersistenceContextType.EXTENDED)
    private EntityManager em;

    ...

    /**
     * With the REQUIRED txn attribute, we can ensure that each time
     * this method is called a new transaction is created and any
     * pending changes in the persistence context are committed.
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void commitTransaction() {
    }

    /** <code>select o from Departments o</code> */
    public List<Departments> getDepartmentsFindAll() {
        return em.createNamedQuery("Departments.findAll").getResultList();
    }

    public <T> T persistEntity(T entity) {
        em.persist(entity);
        return entity;
    }
 }

この例で強調すべきいくつかの重要事項:

  1. Bean レベルの @TransactionAttribute(NOT_SUPPORTED) 設定のため、persistEntity() メソッドが呼び出されたときに txn が開始されません。
  2. @TransactionAttribute(REQUIRED) アノテーションが付けられているため、txn は commitTransaction() メソッドが呼び出されたときにのみ開始され、完了します。

このアプローチにより、JPA が DB で INSERT ステートメントを熱心に発行しなくても、新しいエンティティを永続化できます (および @GeneratedValue を使用して JPA によって生成され、自動割り当てされる ID)。したがって、NOT NULL 列の制約がまだ検証されていないため、プロパティ値を割り当てる前に、エンティティをすぐに永続化できます。commitTransaction() メソッドが呼び出された場合にのみ、JPA は INSERT stmt を実行し、COMMIT を実行します。

さて、上記の利点とともに、私が予想したように多くのことが機能しているようです. 私が抱えている問題は、commitTransaction() が呼び出されるまで、JPQL クエリを介して新しく永続化されたエンティティを取得できないことです。新しく永続化されたエンティティは、永続化コンテキストによって管理されているように見えます。これは、persistEntity() を呼び出した後もエンティティを更新し続けることができ、commitTransaction() を呼び出すと、後続のすべての変更が適切に DB に保存されるためです。ただし、コミットを発行するまで、それらはクエリ キャッシュにあるようには見えません。

コミット時間まで txn を抑制するという私の戦略が、クエリ結果に何らかの影響を与えていると推測しています。

(トランザクションの外部で)永続化されているがコミットされていないエンティティを強制的にJPQLクエリに含めるために使用できるクエリヒントはありますか?

ティア

4

1 に答える 1

2

コミットする前に、flush() を呼び出して変更をデータベースに書き込むことができます。

http://en.wikibooks.org/wiki/Java_Persistence/Persisting#Flushを参照してください。

EntityManager には、各クエリの前にフラッシュをトリガーするフラッシュモードもあります。これはデフォルトで auto に設定されているため、新しいオブジェクトが表示されないのは奇妙です。クエリに別のトランザクションを使用している可能性がありますか? この場合、別のトランザクションは、別のトランザクションのコミットされていない変更、つまりその種のトランザクションのポイントを見ることはありません。

于 2012-05-09T15:01:26.227 に答える