Hibernate源码研究碎得(十二)

Hibernate中"亲子鉴定"

本篇中,我们来看doLoad方法,按上篇的分析方法,我们将这个方法分为三部分:
step1,loadFromSessionCache()的调用和对返回结果的判断.
step2,loadFromSecondLevelCache()的调用和对返回结果的判断.
step3,若上面两个方法的的返回值都为null的话,最后调用loadFromDatasource并返回此方法的返回值.

首先看step1,先不管loadFromDatasource这个方法的执行细节,值得注意的是并没有把结果的判断放入到loadFromDatasource方法里,而是通过判断返回值是否为REMOVED_ENTITY_MARKER或INCONSISTENT_RTN_CLASS_MARKER而分情况地做出log,虽说这两种情况下的最终返回值都是null.另一个值得注意的是虽然loadFromSessionCache可能返回null,但也并没有直接将其返回.这也算是一种编程规范吧:把方法调用及对返回的判断与方法的执行分开,这也很想对Exception的处理,有时根据需要并没有把一些异常都catch起来,而是将其抛出.

关于这个step1,还有一个很值得关注的,那就是特别注意整个系统中debug的安排,这里就特意为debug的需要而创建了两个Object类型的Marker.别的地方虽说也有将debug信息记录下来,但那都是随手而来的debug,不像这特意地绕个弯儿来照顾debug的需要.

有了对step1的分析,doLoad里的step2和step3就没什么特别了的.

下面看loadFromSessionCache方法的执行情况.

由于这里的目标很单一,也就不用再细分N多步了.
首先看第一句,SessionImplementor session = event.getSession();
值得注意的是虽然这个SessionImplementor在onLoad里就从event里获得了,但为了保持代码的精简并没有将那里取得的SessionImplementor作为参数再传到loadFromSessionCache里,而是在这个方法是重新获得,这也正是利用了"指针"的好处,想要什么时就直接获得它的"指针".

接着往下走,从sesion中getEntityUsingInterceptor,这个方法是第一次见,看对这个方法的注释发现了"calling the Interceptor if necessary"这句话.

还没有往下看以前,就觉得有些奇怪,既然这里已经取得了那个Entity为什么不直接返回呢?还要来个处理?接着往下看就发现了这样处理的高明之处:看这个get的Entity的状态,从而决定是否将其返回还是返回那个REMOVED_ENTITY_MARKER或INCONSISTENT_RTN_CLASS_MARKER, 这样的实质也就是任务注册逐层分解,同时也管理好每一次任务分配时的Message反馈,而不是把任务交给你就不管了,同时还要充分考虑到你执行当前任务时可能出现的Message反馈.

以前对EntityEntry这个类老是不能很好地理解,觉得这个名字本身起的就有些怪怪的,Entity就Entity吧,怎么还再来个Entry呢?现在结合这里的实际应用,终于有了很直观的感觉了.
这里有从oldEntry里getStatus的语句,根据这个大致就可以推断出EntityEntry一个用途,那就是Hibernate利用这个类来获得Entity里与Hibernate相关的信息,这样也就理解了Entry一词在这的作用了.

接下往下看,总觉得这段话有点意思:
if ( options.isAllowNulls() ) {
EntityPersister persister = event.getSession().getFactory().getEntityPersister( event.getEntityClassName() );
if ( ! persister.isInstance( old, event.getSession().getEntityMode() ) ) {
return INCONSISTENT_RTN_CLASS_MARKER;
}
}

先不看那个isAllowNulls的作用,下面的isInstance的判断就些不对劲,感觉夫妻俩生了孩子后不是高兴,而是马上给这个孩子做亲子鉴定!本来嘛,这个Entity就是在与之对应的EntityPersister的一手监管下取得的,而这个Entity"独立"后,竟然对这个Entity做"亲子鉴定",有这个必要吗?

当然,我的这个形象的理解是有问题的,Hibernate经过这么久的考验了,这种"亲子鉴定"真正意义上也没有发生.不过通过这个反映出以前我对EntityPersister的理解还不全,需要进一步的修正.在这里也通过这个形象点的比喻来加强对这个问题重视.

下面是另一个方法upgradeLock了,追着看了下,这个方法是从DefaulLoadEventListener的父类AbstractLockUpgradeEventListener里继承来的.

这个方法很长,只能交给下篇来研究了.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值