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

当我们更新logging时,我们可以在Hibernate中使用session.flush() 。 什么是flush()的需要?

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

  • 在执行一些查询之前
  • 当交易被提交时

允许显式刷新Session提供更好的控制,在某些情况下(为了获得一个ID分配,控制会话的大小…),可能需要更好的控制。

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

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

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

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

commit=flush+commit (在function的情况下)

因此,我得出这样的结论:当我们在Session对象上调用方法flush()时,它不会获得提交,而是触发数据库并执行查询并获取回滚

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

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

更多关于Hibernate的网站:

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

你可以使用flush来强制validation约束在一个已知的地方被实现和检测,而不是在事务被提交的时候。 可能是由某些框架逻辑,通过声明逻辑,容器或模板隐式调用commit 。 在这种情况下,抛出的exception可能难以捕捉和处理(代码中可能太高)。

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

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

但是,您将必须在exception后回滚会话。

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

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

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

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

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

几点重要的一点:

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

调用EntityManager#flush确实有副作用 。 它适用于具有生成的ID值(序列值)的实体types:这种ID只有在与基础持久层同步时才可用。 如果在当前事务结束之前需要此ID(例如为了logging日志),则需要刷新会话。