jpa - java/jakarta EE 容器不调用 JPA EntityManager.flush()
问题描述
glassfish 5.1 EE 容器不调用 JPA EntityManager.flush()。
在 Java SE 环境中:
EntityTransaction t = em.getTransaction();
t.begin();
// persist entities
em.persist(entity);
t.commit();
commit() 将刷新持久性上下文中的实体。
Java EE 环境,例如 Glassfish:
@Stateless
public class DataManagerBean {
@PersistenceContext
EntityManager em;
public void persist(Object entity) {
em.persist(entity);
}
}
JSF 豆:
@Named
@ViewScoped
public class FooBean {
@EJB
DataManagerBean dataManagerBean;
public void createFoo() {
dataManagerBean.persist(foo);
}
}
应用程序不能调用 em.getTransaction()。事务由容器管理。在调用 entityManager.close() 之前,不调用 JPA 提供程序 entityManager.flush()。因此,实体未在数据库中创建。
EE环境下,JPA提供者EntityManager获取的数据库连接和容器使用的一样吗?
如果未调用 flush(),EE 容器如何告诉 JPA 提供程序将实体刷新到持久性?
解决方案
这取决于您调用业务方法的方式。简而言之,beeing 默认——事务从您的流程进入第一个业务方法(或拦截器,装饰您的第一个业务方法)开始,并在您的流程离开堆栈中的最后一个业务方法(或拦截器,装饰您的第一个业务方法)时结束。
您可以使用带有适当TransactionAttributeType的@TransactionAttribute注释来管理事务(如果未注释,则默认为 REQUIRED)。例如:
@Stateless
public class DataManagerBean {
@PersistenceContext
EntityManager em;
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void persist(Object entity) {
em.persist(entity);
}
}
在这种情况下,调用 DataManagerBean.persist 会启动新事务并在离开时提交和刷新更改。如果发生错误,它将回滚事务并抛出异常,您可以在调用业务方法时捕获。
推荐阅读
- c# - 用户控制 BringToFront() 事件?
- java - 通过使用多种方法,找到具有给定坐标的三角形的周长
- sql - 如果计数为 0 或未找到行,则返回每个 Select Case 选项的结果
- typescript - typescript 管理 REST 调用和回调
- c# - 使用 pdfSharp 展平 AcroForm 以减小文件大小
- node.js - Nodejs:如何避免循环内nodejs中的异步调用?
- ssl - 仅在一个重写规则上使用 https 的重定向过多
- reactjs - 如何修复 Redux 中可排序可编辑列表的性能
- maven - maven中央存储库替换
- sql-server-2008 - 外键参考