网上很多言论都说load会使用二级缓存而get不会,包括一些hibernate的教材上也这么写的,但是以前在测试中发现,其实get也会使用二级缓存。
很久以前就发现了这个问题,一直没腾出时间研究,今天特意看了下源码(3.2.6.ga),确实如此
先看一下Session的默认实现SessionImpl
get方法会转到fireLoad,loadType的值是LoadEventListener.GET
load方法也是转到fireLoad,不同的是loadType的值是LoadEventListener.LOAD
- private void fireLoad(LoadEvent event, LoadType loadType) {
- errorIfClosed();
- checkTransactionSynchStatus();
- LoadEventListener[] loadEventListener = listeners.getLoadEventListeners();
- for ( int i = 0; i < loadEventListener.length; i++ ) {
- loadEventListener[i].onLoad(event, loadType);
- }
- }
调用loadEventListener的onLoad方法
LoadEventListener的默认实现DefaultLoadEventListener中
最终会转到doLoad方法,options就是前面的loadType
- protected Object doLoad(
- final LoadEvent event,
- final EntityPersister persister,
- final EntityKey keyToLoad,
- final LoadEventListener.LoadType options) throws HibernateException {
- 。。。。。。
- Object entity = loadFromSessionCache( event, keyToLoad, options );//从一级缓存加载
- //如果不为空,直接返回
- 。。。。。。
- entity = loadFromSecondLevelCache(event, persister, options);//从二级缓存加载
- 。。。。。。
- }
loadFromSecondLevelCache即是从二级缓存中查找对象
get和load的区别在于LoadEventListener.LoadType options参数,一个是LoadEventListener.GET,一个是LoadEventListener.LOAD
而在这个方法中,并没有用到options参数
也就是说get和load使用二级缓存的状况是一样的,get也会使用二级缓存
原文来自:http://snz.iteye.com/blog/305634