首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我们必须手动刷新()扩展PersistenceContext中的EntityManager?

为什么我们必须手动刷新()扩展PersistenceContext中的EntityManager?
EN

Stack Overflow用户
提问于 2011-09-01 23:08:36
回答 3查看 15.8K关注 0票数 9

在我们的J2EE应用程序中,我们使用EJB-3有状态bean来允许前端代码创建、修改和保存持久实体(通过JPA-2进行管理)。

它看起来像这样:

代码语言:javascript
复制
@LocalBean
@Stateful
@TransactionAttribute(TransactionAttributeType.NEVER)
public class MyEntityController implements Serializable
{   
    @PersistenceContext(type = PersistenceContextType.EXTENDED)
    private EntityManager em;

    private MyEntity current;

    public void create()
    {
        this.current = new MyEntity();
        em.persist(this.current);
    }

    public void load(Long id)
    {
        this.current = em.find(MyEntity.class, id);
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void save()
    {
        em.flush();
    }
}

非常重要的一点是,为了避免过早提交,事务中只有save()方法,所以如果我们调用create(),就不会在数据库中插入任何内容。

奇怪的是,在save()方法中,我们必须调用em.flush()才能真正命中数据库。事实上,我尝试并发现我们也可以调用em.isOpen()em.getFlushMode(),好吧,任何“与em相关的”。

我不明白这一点。因为save()在一个事务中,所以我认为在方法结束时,事务将被提交,因此持久性实体管理器会自动刷新。为什么我必须手动刷新它?

谢谢,泽维尔

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-09-08 13:34:37

直截了当地说,在您在事务中实际使用javax.transaction.Synchronization之前,将不会有为相关EntityManager注册的对象。

在app-server-land中,我们将创建其中一个对象来执行flush(),并将其注册到javax.transaction.TransactionSynchronizationRegistryjavax.transaction.Transaction。除非有活动的事务,否则无法执行此操作。

这就是它的详细和简短。

是的,应用程序服务器可以很好地保留它提供给有状态bean的资源列表,并将它们自动注册到有状态bean可能启动或参与的每个事务中。这样做的缺点是你完全失去了决定哪些东西进入哪些事务的能力。也许你有2到3个不同的事务在不同的持久化单元上运行,并且正在为一个非常特定的事务在你的扩展持久化上下文中聚合工作。这实际上是一个设计问题,应用服务器应该把这样的决定留给应用本身。

您在事务中使用它,我们将在事务中注册它。这是基本的合同。

附注:根据底层EntityManager的处理方式,对EntityManager的任何持久调用都可能足以在事务结束时导致完全刷新。当然,flush()是最直接、最清晰的,但persist()甚至find()也可以做到这一点。

票数 7
EN

Stack Overflow用户

发布于 2011-09-02 04:39:51

如果使用扩展持久化上下文,则在非事务性方法中对托管实体执行的所有操作都将排队等待写入数据库。一旦在事务上下文中对实体管理器调用flush(),所有排队的更改都会写入数据库。因此,换句话说,当方法退出时,事务性方法本身不会提交更改(就像在CMT中一样),但刷新实体管理器实际上会提交更改。你可以在here上找到这个过程的完整解释

票数 0
EN

Stack Overflow用户

发布于 2014-06-13 17:02:50

因为没有办法知道“何时”客户端完成了会话(扩展范围)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7272354

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档