【问题标题】:What's the use of session.flush() in HibernateHibernate 中 session.flush() 有什么用
【发布时间】:2011-03-14 07:35:21
【问题描述】:

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

【问题讨论】:

    标签: java hibernate orm


    【解决方案1】:

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

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

    允许显式刷新Session 可以提供在某些情况下可能需要的更好控制(获取分配的 ID、控制 Session 的大小......)。

    【讨论】:

    • 请注意,此答案描述了默认休眠行为:可以通过刷新模式设置更改刷新行为。详细信息在docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/…(3.5 版)中。
    • 我找到了document,它的内容与您所说的完全一致,但我有疑问,假设优先级是什么 1) 我有使用代码 id = session.save(obj); 保存对象的类和事务在下一行提交,但 obj 没有保存到 DB,为什么? 2) 我使用session.save(obj); 保存了 obj 并在返回时使用了return obj.getprimaryID(); 在这种情况下,obj 被保存到 DB。那么为什么会发生这种行为呢?
    【解决方案2】:

    正如上面答案中所说的那样,通过调用flush(),我们强制休眠在数据库上执行 SQL 命令。但请理解更改尚未“承诺”。 因此,在刷新之后和提交之前,如果您直接访问数据库(例如从 SQL 提示符)并检查修改的行,您将看不到更改。

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

    【讨论】:

    • 嗯 - 更改可能会稍微可见。例如,未提交的行可以在已插入但未提交的行上创建锁,并延迟同一行被另一个会话插入,直到事务被提交或回滚。所以它不是完全不可见的。
    • 我浏览了整个网络,这就是最终让我明白的答案。谢谢。
    • 将 .flush() 放在 for 循环中然后如果 commit() 在最后执行刷新有什么用?
    • @Kaushik Lele 如果刷新后数据不可见,那么刷新()的意义何在?您能否详细说明一些可以派上用场的更精细的用例?
    【解决方案3】:

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

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

    commit=flush+commit(在功能的情况下)

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

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

    【讨论】:

    • 你能详细说明一下flush需要什么吗?
    【解决方案4】:

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

    Hibernate 网站上的更多信息:

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

    【讨论】:

    • 你能提供一个用户应该担心序列的场景吗?使用休眠是为了让数据库相关的东西对用户透明。当我们“提交”时,刷新会自动发生。什么情况下会刷新但不提交?
    • @KaushikLele 你可以参考这个问题stackoverflow.com/questions/37382872/…
    【解决方案5】:

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

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

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

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

    【讨论】:

      【解决方案6】:

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

      如文档中所述:

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

      冲洗

      flushing是同步持久化状态的过程 与底层数据库的上下文。 EntityManager 和 Hibernate Session 暴露了一组方法,通过这些方法 应用程序开发人员可以更改实体的持久状态。

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

      刷新策略由当前的flushMode给出 运行休眠会话。虽然 JPA 只定义了两次刷新 策略(AUTOCOMMIT),Hibernate 有很多 更广泛的冲洗类型:

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

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

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

      【讨论】:

        【解决方案7】:

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

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

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

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

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

        几个重点:

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

        【讨论】:

          【解决方案8】:

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

          【讨论】:

            【解决方案9】:

            使用此方法可以调用刷新过程。这个过程同步 通过检测状态变化并执行相应的 SQL 语句,将数据库的状态与会话的状态结合起来。

            【讨论】:

              猜你喜欢
              • 2011-09-16
              • 2015-07-24
              • 2011-11-20
              • 1970-01-01
              • 2011-03-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2023-03-26
              相关资源
              最近更新 更多