LoadEventListener中的LoadType
接着上一篇,我们来看方法fireLoad(event, LoadEventListener.GET);
第一个参数就是前面已经准备好的LoadEvent对象,我们重点看下第二个参数.
这个fireLoad的签名是这样的:
fireLoad(LoadEvent event, LoadType loadType)
追着看下LoadType的定义,有点吓一跳,这个类是在接口LoadEventListener中定义的一个static final类型的Class,这还真是第一次见,以前见过在普通类中定义或static或非static内部类的,一真没见过这样在接口中定义的.写动这里,有一个疑问在接口中可不可以定义一个非static也非final的类呢?当在Eclipse里写了如下的定义并保存时,Eclipse没有报错.
public interface MyInterface {
public class MyInnerClass{
}
}
Eclipse没有报错,说明这样的定义是可以的.但又禁不住多想了一下:在接口中声明属性时,编译器都会自动地给加上"public static final"来修饰的,那我在定义MyInnerClass时即使没有显式地写上"static final",编译器在编译时也会不会自动回呢? ------------- 这个问题先放这,毕竟与Hibernate有些远了,等看了相关的说明再做解释.
言归正转.
先围绕着这个LoadType里的属性往前多想一下.LoadType里有如下五个属性:
String类型的name,其余四个都是boolean类型的,依次是nakeEntityReturned,allowNulls,checkDeleted,allowProxyCreation.这四个boolean型的属性会在以后有什么用呢?nakeEntityReturned是否与allowProxyCreation有点重复?总觉得在Hibernate里只要不允许创建Proxy就是nake的了.还有这个allowNulls,这里的null是指什么?是指要load里来的对象属性是否为空(也就是是否延时加载)?还是指这个要加载的对象是否可为Proxy?这样一来又与那两allowProxyCreation的定义有冗余了.这个checkDeleted是check什么的deleted与否?这些问题的进一步澄清还得依赖以后对Hibernate更多的了解与具体应用中的细心体会,不过现在这样一想,最起码的好处是记住了LoadType里有这么四个boolean的属性.
LoadEventListener里定义了这个LoadType类后又在LoadEventListener接口中定义了几个LoadType的常量(当然是public static final的了),依次是RELOAD,GET,LOAD,IMMEDIATE_LOAD,INTERNAL_LOAD_EAGER,INTERNAL_LOAD_LAZY和INTERNAL_LOAD_NULLABLE.
值得注意的是如下两点:
1,这里的RELOAD和GET,它们的name都是"GET",所不同的另外的四个属性不同,那为什么要起相同的name呢?这里面又有什么玄机?
2,比较LOAD和GET,发现它们的allowProxyCreation属性相反:GET里为false,LOAD里为true,是否这就是为什么Session里get方法返回是实打实地从数据库里取出的数据而load只是返回一个proxy对象的根源所在?这个问题先放在这等对get和load方法比较的差不多时再回过头解释.
对LoadEventListener下的LoadType花了点时间后,下面进入fireLoad方法本身.
前两句调用errorIfClosed();checkTransactionSynchStatus();第一个方法可能抛出SessionException异常,即throw new SessionException( "Session is closed!" );这个异常可是很常见的终于知道是怎么抛出了,呵呵...第二个方法再深追就很长了,现在也不大清楚是干啥的,就先放在这.
接着往下走,从已注册的listeners中getLoadEventListeners,再通过for循环的方式依次调用LoadEventListener的onLoad,这个onLoad方法的形参也就是前面准备好的event和loadType了.
接下来进入LoadEventListener接口的实现类DefaultLoadEventListener执行onLoad方法,这样get方法就将进入实质性的执行阶段.
DefaultLoadEventListener中的onLoad方法的实现很长,有五十多行,只能在下一篇里详细研究了,本篇里先简单看下DefaultLoadEventListener这个类.
很好奇这个类里先定义了两个static final修饰的Object类型对象,分别命名为REMOVED_ENTITY_MARKER和INCONSISTENT_RTN_CLASS_MARKER.以前可是没见过直接new一个Object类型对象的,在Hibernate这可真是开眼了.这两个Object对象有什么用?又怎么用呢?毕竟Object里实在没有什么可以拿的出手的方法.
在DefaultLoadEventListener里搜了下后发现return语句后用到了这两个对象,那这样也就是说用Object对象来指向get到的数据了?那怎么能放到Object对象里面呢?Object本身又没有什么专门的方法,再说这两个Object对象已定义为final也就不会再利用"父类变量来指向子类实例"这一特性了. 再细看DefaultLoadEventListener类里对这两个方法的应用,也就是如下的语句:
if ( entity == REMOVED_ENTITY_MARKER ) {
log.debug( "load request found matching entity in context, but it is scheduled for removal; returning null" );
return null;
}
这两Object的作用还真是与它的名字所言,就是作为Marker来用的.那为什么不像平常所见的所样定义个int类型的常量呢?噢,若这样的话与那个entity就没法比较了,不对呀,Java里不是对那些基本类型都有了封装类了吗?那基本类型的封装是在1.5中才有的,为了兼容在Hibernate里没用这个新特性?这样的解释能说的通吗? --- 这个离Hibernate远一点的问题就先放在这,以后再回过头来看吧.
DefaultLoadEventListener类中还有一个属性:LockMode DEFAULT_LOCK_MODE = LockMode.NONE;这个是要干啥用的?搜了下本类中没有用到,再说那个LoadEvent里已有这个属性了,是要与LoadEvent里的那个属性比较?比较的话也不至于再在这声明一个DEFAULT_LOCK_MODE引用,NONE本身是一个static final修饰的,直接要来用就OK了, ... 不对,这里有点东西,NONE是一个static final的没错,不过在这LockMode.NONE这么一声明就相当于又new了一个LockMode对象,可放在这又有什么用呢? --- 先放一放.
DefaultLoadEventListener类中除了onLoad这个接口实现方法外还有十个或private或protected的方法,都是直接或间接地被onLoad调用的,在下一篇中结合onLoad方法再细细研究.
接着上一篇,我们来看方法fireLoad(event, LoadEventListener.GET);
第一个参数就是前面已经准备好的LoadEvent对象,我们重点看下第二个参数.
这个fireLoad的签名是这样的:
fireLoad(LoadEvent event, LoadType loadType)
追着看下LoadType的定义,有点吓一跳,这个类是在接口LoadEventListener中定义的一个static final类型的Class,这还真是第一次见,以前见过在普通类中定义或static或非static内部类的,一真没见过这样在接口中定义的.写动这里,有一个疑问在接口中可不可以定义一个非static也非final的类呢?当在Eclipse里写了如下的定义并保存时,Eclipse没有报错.
public interface MyInterface {
public class MyInnerClass{
}
}
Eclipse没有报错,说明这样的定义是可以的.但又禁不住多想了一下:在接口中声明属性时,编译器都会自动地给加上"public static final"来修饰的,那我在定义MyInnerClass时即使没有显式地写上"static final",编译器在编译时也会不会自动回呢? ------------- 这个问题先放这,毕竟与Hibernate有些远了,等看了相关的说明再做解释.
言归正转.
先围绕着这个LoadType里的属性往前多想一下.LoadType里有如下五个属性:
String类型的name,其余四个都是boolean类型的,依次是nakeEntityReturned,allowNulls,checkDeleted,allowProxyCreation.这四个boolean型的属性会在以后有什么用呢?nakeEntityReturned是否与allowProxyCreation有点重复?总觉得在Hibernate里只要不允许创建Proxy就是nake的了.还有这个allowNulls,这里的null是指什么?是指要load里来的对象属性是否为空(也就是是否延时加载)?还是指这个要加载的对象是否可为Proxy?这样一来又与那两allowProxyCreation的定义有冗余了.这个checkDeleted是check什么的deleted与否?这些问题的进一步澄清还得依赖以后对Hibernate更多的了解与具体应用中的细心体会,不过现在这样一想,最起码的好处是记住了LoadType里有这么四个boolean的属性.
LoadEventListener里定义了这个LoadType类后又在LoadEventListener接口中定义了几个LoadType的常量(当然是public static final的了),依次是RELOAD,GET,LOAD,IMMEDIATE_LOAD,INTERNAL_LOAD_EAGER,INTERNAL_LOAD_LAZY和INTERNAL_LOAD_NULLABLE.
值得注意的是如下两点:
1,这里的RELOAD和GET,它们的name都是"GET",所不同的另外的四个属性不同,那为什么要起相同的name呢?这里面又有什么玄机?
2,比较LOAD和GET,发现它们的allowProxyCreation属性相反:GET里为false,LOAD里为true,是否这就是为什么Session里get方法返回是实打实地从数据库里取出的数据而load只是返回一个proxy对象的根源所在?这个问题先放在这等对get和load方法比较的差不多时再回过头解释.
对LoadEventListener下的LoadType花了点时间后,下面进入fireLoad方法本身.
前两句调用errorIfClosed();checkTransactionSynchStatus();第一个方法可能抛出SessionException异常,即throw new SessionException( "Session is closed!" );这个异常可是很常见的终于知道是怎么抛出了,呵呵...第二个方法再深追就很长了,现在也不大清楚是干啥的,就先放在这.
接着往下走,从已注册的listeners中getLoadEventListeners,再通过for循环的方式依次调用LoadEventListener的onLoad,这个onLoad方法的形参也就是前面准备好的event和loadType了.
接下来进入LoadEventListener接口的实现类DefaultLoadEventListener执行onLoad方法,这样get方法就将进入实质性的执行阶段.
DefaultLoadEventListener中的onLoad方法的实现很长,有五十多行,只能在下一篇里详细研究了,本篇里先简单看下DefaultLoadEventListener这个类.
很好奇这个类里先定义了两个static final修饰的Object类型对象,分别命名为REMOVED_ENTITY_MARKER和INCONSISTENT_RTN_CLASS_MARKER.以前可是没见过直接new一个Object类型对象的,在Hibernate这可真是开眼了.这两个Object对象有什么用?又怎么用呢?毕竟Object里实在没有什么可以拿的出手的方法.
在DefaultLoadEventListener里搜了下后发现return语句后用到了这两个对象,那这样也就是说用Object对象来指向get到的数据了?那怎么能放到Object对象里面呢?Object本身又没有什么专门的方法,再说这两个Object对象已定义为final也就不会再利用"父类变量来指向子类实例"这一特性了. 再细看DefaultLoadEventListener类里对这两个方法的应用,也就是如下的语句:
if ( entity == REMOVED_ENTITY_MARKER ) {
log.debug( "load request found matching entity in context, but it is scheduled for removal; returning null" );
return null;
}
这两Object的作用还真是与它的名字所言,就是作为Marker来用的.那为什么不像平常所见的所样定义个int类型的常量呢?噢,若这样的话与那个entity就没法比较了,不对呀,Java里不是对那些基本类型都有了封装类了吗?那基本类型的封装是在1.5中才有的,为了兼容在Hibernate里没用这个新特性?这样的解释能说的通吗? --- 这个离Hibernate远一点的问题就先放在这,以后再回过头来看吧.
DefaultLoadEventListener类中还有一个属性:LockMode DEFAULT_LOCK_MODE = LockMode.NONE;这个是要干啥用的?搜了下本类中没有用到,再说那个LoadEvent里已有这个属性了,是要与LoadEvent里的那个属性比较?比较的话也不至于再在这声明一个DEFAULT_LOCK_MODE引用,NONE本身是一个static final修饰的,直接要来用就OK了, ... 不对,这里有点东西,NONE是一个static final的没错,不过在这LockMode.NONE这么一声明就相当于又new了一个LockMode对象,可放在这又有什么用呢? --- 先放一放.
DefaultLoadEventListener类中除了onLoad这个接口实现方法外还有十个或private或protected的方法,都是直接或间接地被onLoad调用的,在下一篇中结合onLoad方法再细细研究.