hibernate get load 源码分析
1 hibernate get 主要源码:
public Object get(String entityName, Serializable id) throws HibernateException { LoadEvent event = new LoadEvent(id, entityName, false, this); boolean success = false; try { fireLoad(event, LoadEventListener.GET); success = true; return event.getResult(); } finally { afterOperation(success); } }
load源码:
public Object load(String entityName, Serializable id) throws HibernateException { LoadEvent event = new LoadEvent(id, entityName, false, this); boolean success = false; try { fireLoad( event, LoadEventListener.LOAD ); if ( event.getResult() == null ) { getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id ); } success = true; return event.getResult(); } finally { afterOperation(success); } }
由上可知:hibernate的get和load的加载上前半部分调用方法基本差不多,只是加载类型不一致,一个是get,一个是load;
两种方式同样调用了fireLoad方法,在fireLoad里两者处理相同,都是调用了load事件对应的listener,调用listener的onLoad()方法,
onLoad方法又会调用proxyOrLoad()方法,在proxyOrLoad方法上出现了差异:
Object proxy = persistenceContext.getProxy(keyToLoad); if ( proxy != null ) { return returnNarrowedProxy( event, persister, keyToLoad, options, persistenceContext, proxy ); } else { if ( options.isAllowProxyCreation() ) {//分支1 return createProxyIfNecessary( event, persister, keyToLoad, options, persistenceContext ); } else {//分支2 // return a newly loaded object return load(event, persister, keyToLoad, options); } }
看了如上代码,在看看LoadEventListener.GET和LoadEventListener.LOAD的区别
public static final LoadType GET = new LoadType("GET") .setAllowNulls(true)//允许为空 .setAllowProxyCreation(false)//不允许创建代理对象 .setCheckDeleted(true) .setNakedEntityReturned(false); public static final LoadType LOAD = new LoadType("LOAD") .setAllowNulls(false)//允许为空 .setAllowProxyCreation(true)//不允许创建代理对象 .setCheckDeleted(true) .setNakedEntityReturned(false);
get方式允许为空,不允许创建代理对象;load恰恰相反不允许为空,允许创建代理对象
所以在方法proxyOrLoad()里load会走分支1,get会走分支2
分支1 :get的实际操作在此:
protected Object doLoad( final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final LoadEventListener.LoadType options) { if ( log.isTraceEnabled() ) { log.trace( "attempting to resolve: " + MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() ) ); } Object entity = loadFromSessionCache( event, keyToLoad, options ); if ( entity == REMOVED_ENTITY_MARKER ) { log.debug( "load request found matching entity in context, but it is scheduled for removal; returning null" ); return null; } if ( entity == INCONSISTENT_RTN_CLASS_MARKER ) { log.debug( "load request found matching entity in context, but the matched entity was of an inconsistent return type; returning null" ); return null; } if ( entity != null ) { if ( log.isTraceEnabled() ) { log.trace( "resolved object in session cache: " + MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() ) ); } return entity; } entity = loadFromSecondLevelCache(event, persister, options); if ( entity != null ) { if ( log.isTraceEnabled() ) { log.trace( "resolved object in second-level cache: " + MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() ) ); } return entity; } if ( log.isTraceEnabled() ) { log.trace( "object not resolved in any cache: " + MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() ) ); } return loadFromDatasource(event, persister, keyToLoad, options); }
由上可见:get先去一级缓存里去查找是否存在要返回的对象,如果不存在,则去二级缓存里查找,如果没有则从数据库中加载。
分支2:load加载数据方式:
Object existing = persistenceContext.getEntity( keyToLoad ); if ( existing != null ) { // return existing object or initialized proxy (unless deleted) log.trace( "entity found in session cache" ); if ( options.isCheckDeleted() ) { EntityEntry entry = persistenceContext.getEntry( existing ); Status status = entry.getStatus(); if ( status == Status.DELETED || status == Status.GONE ) { return null; } } return existing; } else { log.trace( "creating new proxy for entity" ); // return new uninitialized proxy Object proxy = persister.createProxy( event.getEntityId(), event.getSession() ); persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey(keyToLoad); persistenceContext.addProxy(keyToLoad, proxy); return proxy; }
load首先会去缓存里查找,否则则创建代理对象(load的代理对象在获取对象属性时究竟如何加载数据?在以后的分析中再做详细分析)
相关推荐
瓜牛呱呱 2020-11-12
柳木木的IT 2020-11-04
yifouhu 2020-11-02
lei0 2020-11-02
源码zanqunet 2020-10-28
源码zanqunet 2020-10-26
一叶梧桐 2020-10-14
码代码的陈同学 2020-10-14
lukezhong 2020-10-14
lzzyok 2020-10-10
anchongnanzi 2020-09-21
clh0 2020-09-18
changcongying 2020-09-17
星辰大海的路上 2020-09-13
abfdada 2020-08-26
mzy000 2020-08-24
shenlanse 2020-08-18
zhujiangtaotaise 2020-08-18
xiemanR 2020-08-17