71

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

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

5 回答 5

59

调用EntityManager.flush();将强制数据立即保存在数据库中,EntityManager.persist()而不是(取决于 EntityManager 的配置方式:FlushModeType(AUTO 或 COMMIT)默认设置为 AUTO,如果设置为,则刷新将自动完成COMMIT 事务提交时数据到底层数据库的持久性会延迟)。

于 2013-07-17T15:21:35.503 回答
25

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

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

具体行为取决于刷新模式是 AUTO 还是 COMMIT。

于 2013-07-17T15:23:02.027 回答
20

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

于 2014-04-09T11:38:08.437 回答
19

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

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

于 2015-07-02T13:33:14.497 回答
5

EntityManager.flush()将实际的 SQL 命令发送到 DB。

持久性框架通常在后台管理事务。所以不能保证刷新的查询会成功提交

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

EntityManager.persist()仅将实体注册到持久性上下文而不向数据库发送任何 SQL 语句。这意味着您不会在persist(). 您只需传递持久对象,并最终在稍后flush()获得 ID。您可以提前打电话给flush()自己获取这些 ID。但同样,它不是事务的结束,因此它可以回滚甚至更多:其他事务/线程/进程/服务器可能会看到更改(通过幻像读取),然后根据数据库引擎和当前和隔离级别消失对外交易!

于 2021-03-24T21:00:53.920 回答