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-26
码代码的陈同学 2020-10-14
lukezhong 2020-10-14
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