我正在使用带有扩展持久性上下文的有状态会话 bean,以及以下 @TransactionAttribute 设置:
@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。
- 一个 txn 仅在调用 commitTransaction() 方法时才开始和完成,因为它被注释为 @TransactionAttribute(REQUIRED)。
这种方法允许持久化新实体(以及它们的 ID 由 JPA 生成和自动分配,使用 @GeneratedValue),而无需 JPA 在数据库中急切地发出 INSERT stmt。因此,我可以在分配任何属性值之前立即保留实体,因为 NOT NULL 列约束尚未验证。只有在调用 commitTransaction() 方法时,JPA 才会执行 INSERT stmt 并执行 COMMIT。
现在,这似乎正如我预期的那样奏效,并具有上面列出的好处。我遇到的问题是,在调用 commitTransaction() 之前,我无法通过 JPQL 查询检索新持久的实体。新持久化的实体似乎由持久化上下文管理,因为我可以在调用persistEntity() 后继续更新它们,并且当我调用commitTransaction() 时,所有后续更改都会正确保存到数据库中。但是,在我发出提交之前,它们似乎并不在查询缓存中。
我猜我在提交时间之前抑制 txn 的策略正在以某种方式影响查询结果。
是否有查询提示可用于强制持久化(在事务之外)但未提交的实体包含在 JPQL 查询中?
TIA