java - 当 Hibernate 刷新一个 Session 时,它如何判断 session 中的哪些对象是脏的?

标签 java hibernate session orm flush

我对 Hibernate 的理解是,当对象从 DB 加载时,它们被添加到 Session 中。在不同的时间点,根据您的配置, session 被刷新。此时,修改的对象被写入数据库。

Hibernate 如何确定哪些对象是“脏的”并且需要写入?

Hibernate 生成的代理是否拦截对字段的赋值,并将对象添加到 Session 中的脏列表?

或者 Hibernate 是否查看 Session 中的每个对象并将其与对象的原始状态进行比较?

还是完全不同的东西?

最佳答案

Hibernate 确实/可以使用字节码生成 (CGLIB),以便在您调用 setter(或什至分配给字段 afaict)时它知道字段是脏的。

这会立即将该字段/对象标记为脏的,但不会减少刷新期间需要进行脏检查的对象的数量。它所做的只是影响 org.hibernate.engine.EntityEntry.requiresDirtyCheck() 的实现。它仍然进行逐个字段的比较以检查是否脏。

我说以上内容是基于最近对源代码 (3.2.6GA) 的拖网搜索,无论增加多少可信度。兴趣点是:

  • SessionImpl.flush() 触发一个 onFlush() 事件。
  • SessionImpl.list() 调用 autoFlushIfRequired() 触发 onAutoFlush() 事件。 (在兴趣表上)。也就是说,查询可以调用刷新。有趣的是,如果没有交易,则不会发生刷新。
  • 这两个事件最终都在 AbstractFlushingEventListener.flushEverythingToExecutions() 中结束,它(在其他有趣的位置)在 flushEntities() 中结束。
  • 循环遍历 session 中的每个实体 (source.getPersistenceContext().getEntityEntries()),调用 DefaultFlushEntityEventListener.onFlushEntity()
  • 您最终会到达 dirtyCheck()。该方法确实对 CGLIB 脏标志进行了一些优化,但我们仍然最终循环遍历每个实体。

关于java - 当 Hibernate 刷新一个 Session 时,它如何判断 session 中的哪些对象是脏的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/82429/

相关文章:

java - 如何获取单选按钮的值并在 TextView 上显示(Java for android)

mysql - 如何将一天添加到sql日期?

c# - 静态对象/变量是否存储在 .NET 上的 Web 应用程序的缓存/ session 中?

Django 用户已注销

java - 并发环境中的 Liquibase

java - 如何从 mysql 表中获取最后 3 个不同的 ID

java - Hibernate:将多对多映射到 Map

java - 如何在刷新之前获取 Hibernate Managed Entity 的数据库快照

database - 如何在集群环境中管理 cfc 的状态

java - 为什么我无法检查字符串中字符的成员资格?