在Hibernate中使用session.flush()有什么用

CHA*_*NTI 99 java orm hibernate

当我们更新记录时,我们可以使用session.flush()Hibernate.有什么需要flush()

Pas*_*ent 131

刷新会话会强制Hibernate同步Session数据库的内存状态(即将更改写入数据库).默认情况下,Hibernate会自动为您更新更改:

  • 在一些查询执行之前
  • 提交事务时

允许显式刷新Session在某些情况下可能需要的更精细控件(分配ID,控制Session的大小,......).

  • 请注意,此答案描述了DEFAULT Hibernate行为:可以通过Flush Mode设置更改刷新行为.详细信息请参见http://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/FlushMode.html(3.5版). (7认同)

Kau*_*ele 65

正如在上面的答案中正确地说,通过调用flush()我们强制hibernate来执行数据库上的SQL命令.但要明白,改变还没有"承诺".因此,在执行flush之后和提交之前,如果直接访问DB(例如从SQL提示符)并检查修改的行,您将看不到更改.

这与打开2个SQL命令会话相同.在提交之前,其他人在1个会话中完成的更改是不可见的.

  • 嗯 - 变化可以略微可见.例如,未提交的行可以在插入但未提交的行上创建锁定,并延迟同一行被另一个会话插入,直到提交或回滚事务为止.所以它并非完全不可见. (9认同)
  • 我已经浏览了整个网络,这就是答案,最终让我得到它.谢谢. (2认同)

Sho*_*ate 26

我只知道当我们调用时,我们session.flush()的语句是在数据库中执行但未提交.

假设我们不在flush()会话对象上调用方法,如果我们调用commit方法,它将在内部执行在数据库上执行语句然后提交的工作.

commit=flush+commit (如果是功能)

因此,我得出结论,当我们在Session对象上调用方法flush()时,它不会得到提交但是会命中数据库并执行查询并获得回滚.

为了提交,我们在Transaction对象上使用commit().


mik*_*iku 13

刷新会话会使当前在会话中的数据与数据库中的数据同步.

有关Hibernate网站的更多信息:

flush()是有用的,因为绝对不能保证Session何时执行JDBC调用,只保证执行它们的顺序 - 除了你使用flush().


rgh*_*ome 11

您可以使用flush强制验证约束在已知位置实现和检测,而不是在提交事务时.它可能是commit由某些框架逻辑,通过声明性逻辑,容器或模板隐式调用的.在这种情况下,抛出的任何异常都可能难以捕获和处理(代码中可能太高).

例如,如果您save()对地址有唯一约束的新EmailAddress对象,则在提交之前不会收到错误.

调用flush()强制插入行,如果有重复则抛出异常.

但是,您必须在异常后回滚会话.


小智 7

flush() 方法使 Hibernate 刷新会话。您可以通过 usingsetFlushMode()方法将 Hibernate 配置为对会话使用刷新模式。要获取当前会话的刷新模式,您可以使用getFlushMode()方法。要检查会话是否脏,您可以使用isDirty()方法。默认情况下,Hibernate 管理会话的刷新。

如文档中所述:

https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html

冲洗

刷新是将持久化上下文的状态与底层数据库同步的过程。的EntityManager和休眠Session暴露了一组方法,通过该应用程序开发者可改变的实体的持久状态。

持久性上下文充当事务性后写缓存,将任何实体状态更改排队。与任何后写缓存一样,更改首先在内存中应用,并在刷新期间与数据库同步。刷新操作获取每个实体状态更改并将其转换为INSERT, UPDATEorDELETE语句。

刷新策略由当前运行的 Hibernate Session的flushMode给出。尽管 JPA 只定义了两种刷新策略(AUTOCOMMIT),但 Hibernate 具有更广泛的刷新类型:

  • ALWAYS: 在每次查询之前刷新会话;
  • AUTO:这是默认模式,仅在必要时刷新会话;
  • COMMIT: Session 尝试延迟刷新直到当前事务提交,尽管它也可能过早刷新;
  • MANUAL:会话刷新被委托给应用程序,它必须Session.flush()显式调用才能应用持久性上下文更改。

默认情况下,Hibernate 使用AUTO刷新模式,在以下情况下触发刷新:

  • 在提交交易之前;
  • 在执行与排队实体操作重叠的 JPQL/HQL 查询之前;
  • 在执行任何没有注册同步的本机 SQL 查询之前。


小智 6

我只想把上面给出的所有答案都放在一起,并将 Flush() 方法与 Session.save() 联系起来,以便给予更多的重视

Hibernate save() 可用于将实体保存到数据库。我们可以在事务之外调用这个方法,这就是为什么我不喜欢这个方法来保存数据。如果我们在没有事务的情况下使用它并且我们在实体之间进行级联,那么除非我们刷新会话,否则只会保存主要实体。

flush():强制会话刷新。它用于将会话数据与数据库同步。

当您调用 session.flush() 时,语句在数据库中执行但不会提交。如果不调用 session.flush() 而调用 session.commit() ,则内部 commit() 方法执行语句并提交。

所以 commit()=flush+commit。所以 session.flush() 只是执行数据库中的语句(但不提交)并且语句不再在内存中。它只是强制会话刷新。

几个重要的点:

我们应该避免在事务边界之外保存,否则将不会保存映射的实体,从而导致数据不一致。忘记刷新会话是很正常的,因为它不会抛出任何异常或警告。默认情况下,Hibernate 将自动为您刷新更改:在提交事务时执行某些查询之前允许显式刷新会话提供在某些情况下可能需要的更好的控制(以获得分配的 ID,控制会话的大小)