私は、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;
}
}
この例で強調すべきいくつかの重要事項:
- Bean レベルの @TransactionAttribute(NOT_SUPPORTED) 設定のため、persistEntity() メソッドが呼び出されたときに txn が開始されません。
- @TransactionAttribute(REQUIRED) アノテーションが付けられているため、txn は commitTransaction() メソッドが呼び出されたときにのみ開始され、完了します。
このアプローチにより、JPA が DB で INSERT ステートメントを熱心に発行しなくても、新しいエンティティを永続化できます (および @GeneratedValue を使用して JPA によって生成され、自動割り当てされる ID)。したがって、NOT NULL 列の制約がまだ検証されていないため、プロパティ値を割り当てる前に、エンティティをすぐに永続化できます。commitTransaction() メソッドが呼び出された場合にのみ、JPA は INSERT stmt を実行し、COMMIT を実行します。
さて、上記の利点とともに、私が予想したように多くのことが機能しているようです. 私が抱えている問題は、commitTransaction() が呼び出されるまで、JPQL クエリを介して新しく永続化されたエンティティを取得できないことです。新しく永続化されたエンティティは、永続化コンテキストによって管理されているように見えます。これは、persistEntity() を呼び出した後もエンティティを更新し続けることができ、commitTransaction() を呼び出すと、後続のすべての変更が適切に DB に保存されるためです。ただし、コミットを発行するまで、それらはクエリ キャッシュにあるようには見えません。
コミット時間まで txn を抑制するという私の戦略が、クエリ結果に何らかの影響を与えていると推測しています。
(トランザクションの外部で)永続化されているがコミットされていないエンティティを強制的にJPQLクエリに含めるために使用できるクエリヒントはありますか?
ティア