当Hibernate刷新会话时,它如何决定会话中的哪些对象是脏的? [英] When Hibernate flushes a Session, how does it decide which objects in the session are dirty?

查看:118
本文介绍了当Hibernate刷新会话时,它如何决定会话中的哪些对象是脏的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



Hibernate如何决定哪些对象是'脏'并且需要被写入?

Hibernate生成的代理是否截获了字段的赋值,并将该对象添加到会话中的一个脏列表中?



或者Hibernate的外观在会话中的每个对象,并与对象的原始状态进行比较?



或者完全不同的东西?

解决方案

Hibernate可以/可以使用字节码生成(CGLIB),以便在您调用setter时(或者甚至分配给字段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()结束。该方法对CGLIB脏标志做了一些优化,但我们仍然结束了对每个实体的循环。


My understanding of Hibernate is that as objects are loaded from the DB they are added to the Session. At various points, depending on your configuration, the session is flushed. At this point, modified objects are written to the database.

How does Hibernate decide which objects are 'dirty' and need to be written?

Do the proxies generated by Hibernate intercept assignments to fields, and add the object to a dirty list in the Session?

Or does Hibernate look at each object in the Session and compare it with the objects original state?

Or something completely different?

解决方案

Hibernate does/can use bytecode generation (CGLIB) so that it knows a field is dirty as soon as you call the setter (or even assign to the field afaict).

This immediately marks that field/object as dirty, but doesn't reduce the number of objects that need to be dirty-checked during flush. All it does is impact the implementation of org.hibernate.engine.EntityEntry.requiresDirtyCheck(). It still does a field-by-field comparison to check for dirtiness.

I say the above based on a recent trawl through the source code (3.2.6GA), with whatever credibility that adds. Points of interest are:

  • SessionImpl.flush() triggers an onFlush() event.
  • SessionImpl.list() calls autoFlushIfRequired() which triggers an onAutoFlush() event. (on the tables-of-interest). That is, queries can invoke a flush. Interestingly, no flush occurs if there is no transaction.
  • Both those events eventually end up in AbstractFlushingEventListener.flushEverythingToExecutions(), which ends up (amongst other interesting locations) at flushEntities().
  • That loops over every entity in the session (source.getPersistenceContext().getEntityEntries()) calling DefaultFlushEntityEventListener.onFlushEntity().
  • You eventually end up at dirtyCheck(). That method does make some optimizations wrt to CGLIB dirty flags, but we've still ended up looping over every entity.

这篇关于当Hibernate刷新会话时,它如何决定会话中的哪些对象是脏的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆