首页 > 解决方案 > 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 提供程序将实体刷新到持久性?

标签: jpajakarta-eejava-ee-8

解决方案


这取决于您调用业务方法的方式。简而言之,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 会启动新事务并在离开时提交和刷新更改。如果发生错误,它将回滚事务并抛出异常,您可以在调用业务方法时捕获。


推荐阅读