当前位置:  开发笔记 > 编程语言 > 正文

当Hibernate刷新会话时,它如何判断会话中的哪些对象是脏的?

如何解决《当Hibernate刷新会话时,它如何判断会话中的哪些对象是脏的?》经验,为你挑选了2个好方法。

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

Hibernate如何确定哪些对象是"脏的"并且需要编写?

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

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

还是完全不同的东西?



1> Matt Quail..:

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脏标志进行了一些优化,但我们仍然最终循环遍历每个实体.



2> alasdairg..:

Hibernate会获取加载到Session中的每个对象的状态的快照.在刷新时,会话中的每个对象与其对应的快照进行比较,以确定哪些对象是脏的.根据需要发出SQL语句,并更新快照以反映(现在干净的)Session对象的状态.

推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有