问题描述
我对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 anonFlush()
event.SessionImpl.list()
callsautoFlushIfRequired()
which triggers anonAutoFlush()
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) atflushEntities()
. - That loops over every entity in the session (
source.getPersistenceContext().getEntityEntries()
) callingDefaultFlushEntityEventListener.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刷新会话时,它如何决定会话中的哪些对象是脏的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!