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的代理对象在获取对象属性时究竟如何加载数据?在以后的分析中再做详细分析)

   

相关推荐