我对 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/