我有一个EJB,我将对象保存到数据库。在我看到的一个例子中,一旦保存了这个数据(EntityManager.persist),就会调用EntityManager.flush();为什么我需要这样做?我保存的对象没有附加,以后不会在方法中使用。事实上,一旦保存,方法返回,我希望资源被释放。 (示例代码也会在删除调用上执行此操作。)
if (somecondition) {
entityManager.persist(unAttachedEntity);
} else {
attachedEntityObject.setId(unAttachedEntity.getId());
}
entityManager.flush();
答案 0 :(得分:42)
对EntityManager.flush();
的调用将强制数据立即保留在数据库中,因为EntityManager.persist()
不会(取决于EntityManager的配置方式:FlushModeType (AUTO或COMMIT)默认情况下,它设置为AUTO,如果将其设置为COMMIT,将自动完成刷新,当提交事务时,数据的持久性将被延迟。
答案 1 :(得分:16)
在提交事务之前,可以使用EntityManager.flush()
操作对数据库进行写入所有更改。默认情况下,JPA通常不会在提交事务之前将更改写入数据库。这通常是可取的,因为它避免了数据库访问,资源和锁定,直到需要。它还允许对数据库写入进行排序和批处理以实现最佳数据库访问,并保持完整性约束并避免死锁。这意味着当您调用persist,merge或删除数据库时,DML INSERT
,UPDATE
,DELETE
不会执行,直到提交,或直到触发刷新。
答案 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。但这又不是事务结束,所以它可以回滚甚至更多:其他事务/线程/进程/服务器可能会看到更改(通过幻读),然后消失取决于数据库引擎和当前和外部事务的隔离级别!