【发布时间】:2011-03-14 07:35:21
【问题描述】:
当我们更新记录时,我们可以在 Hibernate 中使用session.flush()。 flush()需要什么?
【问题讨论】:
当我们更新记录时,我们可以在 Hibernate 中使用session.flush()。 flush()需要什么?
【问题讨论】:
刷新会话会强制 Hibernate 将 Session 的内存状态与数据库同步(即将更改写入数据库)。默认情况下,Hibernate 会自动为您刷新更改:
允许显式刷新Session 可以提供在某些情况下可能需要的更好控制(获取分配的 ID、控制 Session 的大小......)。
【讨论】:
id = session.save(obj); 保存对象的类和事务在下一行提交,但 obj 没有保存到 DB,为什么? 2) 我使用session.save(obj); 保存了 obj 并在返回时使用了return obj.getprimaryID(); 在这种情况下,obj 被保存到 DB。那么为什么会发生这种行为呢?
正如上面答案中所说的那样,通过调用flush(),我们强制休眠在数据库上执行 SQL 命令。但请理解更改尚未“承诺”。
因此,在刷新之后和提交之前,如果您直接访问数据库(例如从 SQL 提示符)并检查修改的行,您将看不到更改。
这与打开 2 个 SQL 命令会话相同。并且在 1 个会话中完成的更改在提交之前对其他人不可见。
【讨论】:
我只知道当我们调用session.flush() 时,我们的语句在数据库中执行但没有提交。
假设我们不在会话对象上调用flush() 方法,如果我们调用commit 方法,它将在内部完成在数据库上执行语句然后提交的工作。
commit=flush+commit(在功能的情况下)
因此,我得出结论,当我们在 Session 对象上调用方法 flush() 时,它不会得到提交,而是命中数据库并执行查询并得到回滚。
为了提交,我们在 Transaction 对象上使用 commit()。
【讨论】:
刷新 Session 获取当前在会话中的数据与数据库中的数据同步。
Hibernate 网站上的更多信息:
flush() 很有用,因为绝对不能保证 Session 何时执行 JDBC 调用,只能保证它们的执行顺序 - 除非您使用 flush()。
【讨论】:
您可以使用flush 来强制在已知位置而不是在提交事务时实现和检测验证约束。 commit 可能被某些框架逻辑、通过声明性逻辑、容器或模板隐式调用。在这种情况下,任何抛出的异常都可能难以捕获和处理(它可能在代码中太高了)。
例如,如果您save() 一个新的 EmailAddress 对象,该对象对地址具有唯一约束,则在您提交之前不会收到错误。
调用flush() 强制插入行,如果有重复则抛出异常。
但是,您必须在异常发生后回滚会话。
【讨论】:
flush() 方法导致 Hibernate 刷新会话。您可以使用 setFlushMode() 方法将 Hibernate 配置为对会话使用刷新模式。要获取当前会话的刷新模式,可以使用getFlushMode() 方法。要检查会话是否脏,可以使用isDirty() 方法。默认情况下,Hibernate 管理会话的刷新。
如文档中所述:
https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html
冲洗
flushing是同步持久化状态的过程 与底层数据库的上下文。
EntityManager和 HibernateSession暴露了一组方法,通过这些方法 应用程序开发人员可以更改实体的持久状态。持久性上下文充当事务性后写缓存, 排队任何实体状态更改。像任何后写缓存一样,更改 首先在内存中应用并在期间与数据库同步 冲洗时间。刷新操作需要每个实体状态更改和 将其转换为
INSERT、UPDATE或DELETE语句。刷新策略由当前的flushMode给出 运行休眠会话。虽然 JPA 只定义了两次刷新 策略(
AUTO和COMMIT),Hibernate 有很多 更广泛的冲洗类型:
ALWAYS:在每次查询之前刷新 Session;AUTO:这是默认模式,仅在必要时刷新会话;COMMIT: Session 尝试延迟刷新,直到当前事务被提交,尽管它也可能过早刷新;MANUAL:会话刷新被委托给应用程序,它必须显式调用Session.flush()才能应用 持久性上下文更改。默认情况下,Hibernate 使用
AUTO刷新模式,该模式会触发 在以下情况下刷新:
- 在提交交易之前;
- 在执行与排队实体操作重叠的 JPQL/HQL 查询之前;
- 在执行任何未注册同步的本机 SQL 查询之前。
【讨论】:
我只想将上面给出的所有答案都包含在内,并将 Flush() 方法与 Session.save() 联系起来,以便更加重视
Hibernate save() 可用于将实体保存到数据库。我们可以在事务之外调用这个方法,所以我不喜欢用这个方法来保存数据。如果我们在没有事务的情况下使用它并且我们在实体之间有级联,那么除非我们刷新会话,否则只有主实体会被保存。
flush():强制会话刷新。用于将会话数据与数据库同步。
当您调用 session.flush() 时,语句在数据库中执行但不会提交。 如果您不调用 session.flush() 并且如果您调用 session.commit() ,则内部 commit() 方法会执行该语句并提交。
所以提交()=刷新+提交。 所以 session.flush() 只是执行数据库中的语句(而不是提交)并且语句不再在内存中。它只是强制会话刷新。
几个重点:
我们应该避免在事务边界之外保存,否则映射的实体将不会被保存导致数据不一致。忘记刷新会话是很正常的,因为它不会引发任何异常或警告。 默认情况下,Hibernate 会自动为您刷新更改: 在一些查询执行之前 提交事务时 允许显式刷新 Session 提供了在某些情况下可能需要的更好的控制(获取分配的 ID,控制 Session 的大小)
【讨论】:
调用EntityManager#flush 确实有副作用。它方便地用于具有生成 ID 值(序列值)的实体类型:这样的 ID 仅在与底层持久层同步时可用。如果在当前事务结束之前需要此 ID(例如用于记录目的),则需要刷新会话。
【讨论】:
使用此方法可以调用刷新过程。这个过程同步 通过检测状态变化并执行相应的 SQL 语句,将数据库的状态与会话的状态结合起来。
【讨论】: