当休眠刷新会话时,它如何确定会话中的哪些对象是脏的?
我对Hibernate的理解是,当对象从数据库加载时,它们会被添加到会话中。在不同时间点,根据您的配置,会话会被刷新。此时,修改后的对象将写入数据库。
Hibernate如何决定哪些对象是“脏的”并且需要写入?
Hibernate 生成的代理是否会截获字段的分配,并将对象添加到会话中的脏列表中?
或者,休眠会查看会话中的每个对象并将其与对象原始状态进行比较?
还是完全不同的东西?
我对Hibernate的理解是,当对象从数据库加载时,它们会被添加到会话中。在不同时间点,根据您的配置,会话会被刷新。此时,修改后的对象将写入数据库。
Hibernate如何决定哪些对象是“脏的”并且需要写入?
Hibernate 生成的代理是否会截获字段的分配,并将对象添加到会话中的脏列表中?
或者,休眠会查看会话中的每个对象并将其与对象原始状态进行比较?
还是完全不同的东西?
Hibernate确实/可以使用字节码生成(CGLIB),这样一旦您调用设置器(甚至分配给字段afaict),它就会知道字段是脏的。
这会立即将该字段/对象标记为脏,但不会减少在刷新过程中需要进行脏检查的对象数。它所做的只是影响 的实现。它仍然会逐个字段进行比较以检查脏污。org.hibernate.engine.EntityEntry.requiresDirtyCheck()
我说以上是基于最近对源代码(3.2.6GA)的拖网,无论增加什么可信度。兴趣点是:
SessionImpl.flush()
触发事件。onFlush()
SessionImpl.list()
触发事件的调用。(在感兴趣的表格上)。也就是说,查询可以调用刷新。有趣的是,如果没有事务,则不会发生刷新。autoFlushIfRequired()
onAutoFlush()
AbstractFlushingEventListener.flushEverythingToExecutions()
flushEntities()
source.getPersistenceContext().getEntityEntries()
DefaultFlushEntityEventListener.onFlushEntity()
dirtyCheck()
休眠会拍摄加载到会话中的每个对象的状态快照。刷新时,会话中的每个对象都与其相应的快照进行比较,以确定哪些对象是脏的。SQL 语句根据需要发出,并且快照将更新以反映(现在为干净的)会话对象的状态。