EntityManager.persist()之后会发生什么

时间:2012-01-15 11:18:17

标签: java jpa java-ee-6 glassfish-3

EntityManger注入了@PersistenceContext注释。这是我的“DAO / Repository”类中没有注释的方法。这个类被注入到需要从/向数据库获取数据的EJB中。

到目前为止,我认为在完成下面的持久化方法之后,会刷新persistencecontext并将数据存储到数据库中,但是从我的应用程序中发生的事情开始,我开始怀疑这一点。我已经在Glassfish中创建了数据源和连接池,所以我知道使用容器管理的事务,但是我没有使用任何事务注释。

有人可以为我提供一些亮点吗?

public void persist(QuestionFeedback questionFeedback) {
    questionFeedback.setCreated(new Date());
    entityManager.persist(questionFeedback);
}

使用Glassfish 3,Java EE6兼容性

3 个答案:

答案 0 :(得分:5)

persist方法使实体持久化,但尚未将更改写入数据库。这通常发生在事务提交时(提供者可以自由地优化它,它可能更早发生)。

使用flush可以强制写入更早发生,但它仍然只对参与当前事务的代码可见。为了使写入永久(对所有外部代码可见),仍然需要提交事务。

没有任何显式注释,默认情况下,您的EJB bean将是事务性的。

答案 1 :(得分:0)

如果您不使用任何交易注释,则默认将是所需的交易。因此,您的DAO将在事务中运行,并且持久化上下文将不会在事务提交时刷新。

来自TransactionAttribute上的JavaDoc:

  

如果未指定TransactionAttribute批注,并且bean使用容器管理的事务划分,则假定REQUIRED事务属性的语义。

来自FlushModeType上的JavaDoc:

  

在事务中执行查询时,如果在Query或TypedQuery对象上设置了FlushModeType.AUTO,或者持久化上下文的刷新模式设置为AUTO(默认值)并且尚未指定刷新模式设置在Query或TypedQuery对象中,持久性提供程序负责确保对持久性上下文中可能影响查询结果的所有实体的状态的所有更新对于查询的处理是可见的。

这意味着如果您使用的结果可能会受到该刷新影响的查询,则可以更早地刷新持久性上下文。

答案 2 :(得分:0)

因为EntityManager是通过@PersistenceContext注释注入的,所以您肯定使用容器管理的事务。

无论如何,你的假设持续导致事务提交是错误的。通过persist执行的更改是在提交中对数据库进行的。 EntityManager的文档说"通过调用persist"来实现新实例的管理和持久性。在这种情况下,"变得坚持不懈"并不意味着实体在那一刻被持久化到数据库。在调用persist的那一刻,实体被持久化为PersistenceContext。然后,稍后在事务提交时将其持久保存到数据库。

因为您没有为方法使用任何@TransactionAttribute注释,所以默认将适用。默认值为TransactionAttributeType.REQUIRED。这将导致容器在调用第一个业务方法时创建事务,并将其传播到其他方法。完成对第一个业务方法的调用后,您的事务将提交。然后您的更改将在数据库中(如果未执行回滚)。