一尘不染

当Hibernate刷新一个Session时,它如何确定Session中的哪些对象是脏的?

hibernate

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

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

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

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

还是完全不同的东西?


阅读 262

收藏
2020-06-20

共1个答案

一尘不染

Hibernate确实/可以使用字节码生成(CGLIB),以便它在您调用setter(甚至分配给字段faict)后立即知道该字段是脏的。

这会立即将该字段/对象标记为脏,但不会减少刷新期间需要进行脏检查的对象的数量。它所做的一切都会影响的实施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脏标志进行了一些优化,但是我们仍然最终遍历了每个实体。
2020-06-20