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

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

问题描述

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

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.

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

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

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

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

还是Hibernate会查看Session中的每个对象,并与对象的原始状态进行比较?

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

或者完全不同的东西?

推荐答案

Hibernate 确实/可以使用字节码生成 (CGLIB) 以便在您调用 setter(甚至分配给字段 afaict).

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).

这会立即将该字段/对象标记为脏,但不会减少刷新期间需要进行脏检查的对象数量.它所做的只是影响 org.hibernate.engine.EntityEntry.requiresDirtyCheck() 的实现.它仍然进行逐个字段的比较以检查是否脏.

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.

我是根据最近对源代码 (3.2.6GA) 的搜索结果说的,无论增加什么可信度.兴趣点是:

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() 触发 onFlush() 事件.
  • SessionImpl.list() 调用触发 onAutoFlush() 事件的 autoFlushIfRequired().(在兴趣表上).也就是说,查询可以调用刷新.有趣的是,如果没有事务,则不会发生刷新.
  • 这两个事件最终都在 AbstractFlushingEventListener.flushEverythingToExecutions() 中结束,后者在 flushEntities() 处结束(以及其他有趣的位置).
  • 循环遍历会话中的每个实体 (source.getPersistenceContext().getEntityEntries()) 调用 DefaultFlushEntityEventListener.onFlushEntity().
  • 您最终会遇到 dirtyCheck().该方法确实对 CGLIB 脏标志进行了一些优化,但我们最终还是遍历了每个实体.
  • 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 刷新 Session 时,它如何确定会话中的哪些对象是脏的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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