我正在使用带有EXTENDED持久化上下文的有状态会话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;
}
}
在这个例子中要提出一些重要的事情:
这种方法允许新实体被持久化(并且它们的ID由JPA生成并使用@GeneratedValue自动分配),而JPA并不急切地在DB中发布INSERT stmt。因此,在分配任何属性值之前,我可以立即持久保存实体,因为尚未验证NOT NULL列约束。只有在调用commitTransaction()方法时,JPA才会执行INSERT stmt并执行COMMIT。
现在,有很多似乎按照我的预期工作,具有上面列出的好处。我遇到的问题是我无法通过JPQL查询检索新的持久化实体,直到调用commitTransaction()为止。新持久化实体似乎由持久化上下文管理,因为我可以在调用persistEntity()之后继续更新它们,并且当我调用commitTransaction()时,所有后续更改都会正确保存到数据库中。但是,在我发出提交之前,它们似乎不在查询缓存中。
我猜我在提交时间之前抑制txn的策略会以某种方式影响查询结果。
是否有一个查询提示我可以用来强制持久化(在事务之外)但未提交的实体要包含在JPQL查询中?
TIA
答案 0 :(得分:1)
您可以在提交之前调用flush()将更改写入数据库。
请参阅http://en.wikibooks.org/wiki/Java_Persistence/Persisting#Flush
EntityManager上还有一个刷新模式,它会在每个查询之前触发刷新,默认为auto,所以很奇怪你看不到新对象。也许您正在为查询使用不同的事务?在这种情况下,另一个事务永远不会看到另一个事务的未提交的更改,即事务的那种点。