EntityManager.flush做了什么以及为什么需要使用它?

时间:2013-07-17 15:00:12

标签: java jpa entitymanager

我有一个EJB,我将对象保存到数据库。在我看到的一个例子中,一旦保存了这个数据(EntityManager.persist),就会调用EntityManager.flush();为什么我需要这样做?我保存的对象没有附加,以后不会在方法中使用。事实上,一旦保存,方法返回,我希望资源被释放。 (示例代码也会在删除调用上执行此操作。)

if (somecondition) {
    entityManager.persist(unAttachedEntity);
} else {
    attachedEntityObject.setId(unAttachedEntity.getId());
}
entityManager.flush();

5 个答案:

答案 0 :(得分:42)

EntityManager.flush();的调用将强制数据立即保留在数据库中,因为EntityManager.persist()不会(取决于EntityManager的配置方式:FlushModeType (AUTO或COMMIT)默认情况下,它设置为AUTO,如果将其设置为COMMIT,将自动完成刷新,当提交事务时,数据的持久性将被延迟。

答案 1 :(得分:16)

在提交事务之前,可以使用EntityManager.flush()操作对数据库进行写入所有更改。默认情况下,JPA通常不会在提交事务之前将更改写入数据库。这通常是可取的,因为它避免了数据库访问,资源和锁定,直到需要。它还允许对数据库写入进行排序和批处理以实现最佳数据库访问,并保持完整性约束并避免死锁。这意味着当您调用persist,merge或删除数据库时,DML INSERTUPDATEDELETE不会执行,直到提交,或直到触发刷新。

答案 2 :(得分:15)

EntityManager.persist()使实体持久化,而EntityManager.flush()实际上在您的数据库上运行查询。

因此,当您调用EntityManager.flush()时,将在数据库中执行插入/更新/删除关联实体的查询。此时将知道任何约束失败(列宽,数据类型,外键)。

具体行为取决于flush-mode是AUTO还是COMMIT。

答案 3 :(得分:8)

因此,当您致电EntityManager.persist()时,它只会使实体由EntityManager管理,并将其(实体实例)添加到Persistence Context。显式flush()将使现在驻留在Persistence Context中的实体移动到数据库(使用SQL)。

如果没有flush(),那么(将实体从Persistence Context移动到数据库)将在提交与此Persistence Context关联的事务时发生。

答案 4 :(得分:2)

EntityManager.flush() 向数据库发送实际的 SQL 命令。

持久性框架通常在幕后管理事务。 因此无法保证刷新的查询会成功提交

EntityManager.flush() 总是在事务提交之前由持久性框架在后台自动调用。

EntityManager.persist() 只将实体注册到持久化上下文,而不向数据库发送任何 SQL 语句。这意味着您不会在 persist() 之后获得自动生成的 ID。您只需传递持久对象,最终在 flush() 之后它会获得 ID。您可以自己致电 flush() 以提前获取这些 ID。但这又不是事务结束,所以它可以回滚甚至更多:其他事务/线程/进程/服务器可能会看到更改(通过幻读),然后消失取决于数据库引擎和当前和外部事务的隔离级别!