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

时间:2010-07-10 18:11:38

标签: java hibernate orm

当我们更新记录时,我们可以将session.flush()与Hibernate一起使用。 flush()需要什么?

9 个答案:

答案 0 :(得分:122)

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

  • 在某些查询执行之前
  • 提交交易时

允许显式刷新Session可以在某些情况下提供更精细的控制(分配ID,控制会话大小......)。

答案 1 :(得分:61)

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

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

答案 2 :(得分:21)

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

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

commit=flush+commit(如果是功能性的话)

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

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

答案 3 :(得分:12)

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

有关Hibernate网站的更多信息:

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

答案 4 :(得分:9)

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

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

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

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

答案 5 :(得分:3)

我想赞成上面给出的所有答案,并将Flush()方法与Session.save()联系起来,以便更加重视

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

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

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

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

几点重要:

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

答案 6 :(得分:1)

调用EntityManager#flush确实有副作用。它方便地用于具有生成的ID值(序列值)的实体类型:这样的ID仅在与底层持久层同步时可用。如果在当前事务结束之前需要此ID(例如,为了记录日志),则需要刷新会话。

答案 7 :(得分:1)

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

如文档中所述:

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

  

冲洗

     

刷新是同步持久性状态的过程   基础数据库的上下文。 EntityManager和   休眠Session公开了一组方法,通过这些方法,   应用程序开发人员可以更改实体的持久状态。

     

持久性上下文充当事务后写式缓存,   排队任何实体状态更改。像任何写后缓存一样,更改   首先在内存中应用,并在此期间与数据库同步   冲洗时间。刷新操作会进行每个实体状态更改,并且   将其转换为INSERTUPDATEDELETE语句。

     

刷新策略由当前的flushMode给出   运行休眠会话。尽管JPA仅定义了两次冲洗   策略(AUTOCOMMIT),Hibernate有很多优势   冲洗类型的范围更广:

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

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

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

答案 8 :(得分:0)

使用此方法可以唤起刷新过程。此过程同步  通过检测状态变化并执行相应的SQL语句,将数据库的状态与会话状态进行关联。