📄 defaultloadeventlistener.java
字号:
//$Id: DefaultLoadEventListener.java,v 1.7 2005/04/03 01:52:14 oneovthafew Exp $package org.hibernate.event.def;import java.io.Serializable;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.hibernate.Hibernate;import org.hibernate.HibernateException;import org.hibernate.LockMode;import org.hibernate.NonUniqueObjectException;import org.hibernate.ObjectDeletedException;import org.hibernate.ObjectNotFoundException;import org.hibernate.PersistentObjectException;import org.hibernate.cache.CacheConcurrencyStrategy;import org.hibernate.cache.CacheKey;import org.hibernate.cache.entry.CacheEntry;import org.hibernate.engine.EntityEntry;import org.hibernate.engine.EntityKey;import org.hibernate.engine.PersistenceContext;import org.hibernate.engine.SessionFactoryImplementor;import org.hibernate.engine.Status;import org.hibernate.engine.TwoPhaseLoad;import org.hibernate.engine.Versioning;import org.hibernate.event.LoadEvent;import org.hibernate.event.LoadEventListener;import org.hibernate.event.PostLoadEvent;import org.hibernate.engine.SessionImplementor;import org.hibernate.persister.entity.EntityPersister;import org.hibernate.pretty.MessageHelper;import org.hibernate.proxy.HibernateProxy;import org.hibernate.type.Type;import org.hibernate.type.TypeFactory;/** * Defines the default load event listeners used by hibernate for loading entities * in response to generated load events. * * @author Steve Ebersole */public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener implements LoadEventListener { private static final Log log = LogFactory.getLog(DefaultLoadEventListener.class); public static final LockMode DEFAULT_LOCK_MODE = LockMode.NONE; /** * Handle the given load event. * * @param event The load event to be handled. * @return The result (i.e., the loaded entity). * @throws HibernateException */ public Object onLoad(LoadEvent event, LoadEventListener.LoadType loadType) throws HibernateException { final SessionImplementor source = event.getSession(); EntityPersister persister; if ( event.getInstanceToLoad() != null ) { persister = source.getEntityPersister( null, event.getInstanceToLoad() ); //the load() which takes an entity does not pass an entityName event.setEntityClassName( event.getInstanceToLoad().getClass().getName() ); } else { persister = source.getFactory().getEntityPersister( event.getEntityClassName() ); } if ( persister == null ) { throw new HibernateException( "Unable to locate persister: " + event.getEntityClassName() ); } //log.debug("Got persister [" + persister + "]"); EntityKey keyToLoad = new EntityKey( event.getEntityId(), persister, source.getEntityMode() ); Options options = new Options(); //TODO: the options should be properties of the event, // get rid of this ugly switch statement if ( event.getInstanceToLoad() != null ) { options.setAllowNulls(false); options.setAllowProxyCreation(false); options.setCheckDeleted(true); options.setImmediateLoad(false); } else if ( loadType == GET ) { options.setAllowNulls(true); options.setAllowProxyCreation(false); options.setCheckDeleted(true); options.setImmediateLoad(false); } else if ( loadType == LOAD ) { options.setAllowNulls(false); options.setAllowProxyCreation(true); options.setCheckDeleted(true); options.setImmediateLoad(false); } else if ( loadType == IMMEDIATE_LOAD ) { options.setAllowNulls(false); options.setAllowProxyCreation(false); options.setCheckDeleted(true); options.setImmediateLoad(true); } else if ( loadType == INTERNAL_LOAD ) { options.setAllowNulls(false); options.setAllowProxyCreation(true); options.setCheckDeleted(false); options.setImmediateLoad(false); } else if ( loadType == INTERNAL_LOAD_NULLABLE ) { options.setAllowNulls(true); options.setAllowProxyCreation(false); options.setCheckDeleted(false); options.setImmediateLoad(false); } try { if ( options.isImmediateLoad() ) { //do not return a proxy! //(this option inidicates we are initializing a proxy) return load(event, persister, keyToLoad, options); } else { //return a proxy if appropriate return event.getLockMode() == LockMode.NONE ? proxyOrLoad(event, persister, keyToLoad, options) : lockAndLoad(event, persister, keyToLoad, options, source); } } catch(HibernateException e) { log.info("Error performing load command", e); throw e; } } protected Object load( final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final Options options) throws HibernateException { return load(event, persister, keyToLoad, options, null); } /** * Perfoms the load of an entity. * * @return The loaded entity. * @throws HibernateException */ protected Object load( final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final Options options, final Object result) throws HibernateException { if ( event.getInstanceToLoad() != null ) { if ( event.getSession().getPersistenceContext().getEntry( event.getInstanceToLoad() ) != null ) { throw new PersistentObjectException( "attempted to load into an instance that was already associated with the session: " + MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() ) ); } persister.setIdentifier( event.getInstanceToLoad(), event.getEntityId(), event.getSession().getEntityMode() ); } Object entity = doLoad(event, persister, keyToLoad, options, result); boolean isOptionalInstance = event.getInstanceToLoad() != null; if ( !options.isAllowNulls() || isOptionalInstance ) { ObjectNotFoundException.throwIfNull( entity, event.getEntityId(), event.getEntityClassName() ); } if ( isOptionalInstance && entity != event.getInstanceToLoad() ) { throw new NonUniqueObjectException( event.getEntityId(), event.getEntityClassName() ); } return entity; } /** * Based on configured options, will either return a pre-existing proxy, * generate a new proxy, or perform an actual load. * * @return The result of the proxy/load operation. * @throws HibernateException */ protected Object proxyOrLoad( final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final Options options) throws HibernateException { if ( log.isTraceEnabled() ) { log.trace( "loading entity: " + MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() ) ); } if ( !persister.hasProxy() ) { // this class has no proxies (so do a shortcut) return load(event, persister, keyToLoad, options); } else { SessionImplementor source = event.getSession(); final PersistenceContext persistenceContext = source.getPersistenceContext(); Object existing = persistenceContext.getEntity(keyToLoad); if ( existing != null ) { // return existing object or initialized proxy (unless deleted) log.trace("entity found in session cache"); Object proxy = persistenceContext.proxyFor( persister, keyToLoad, // we still need to call load(), to do exception checking // and lock upgrade, but pass the entity we already found // to avoid double-lookup load(event, persister, keyToLoad, options, existing) ); //force the proxy to resolve itself Hibernate.initialize(proxy); return proxy; } else { // look for a proxy Object proxy = persistenceContext.getProxy(keyToLoad); if ( proxy != null ) { log.trace("entity proxy found in session cache"); Object impl; if ( options.isAllowProxyCreation() ) { impl = null; } else { //force initialization of the proxy impl = ( (HibernateProxy) proxy ).getHibernateLazyInitializer().getImplementation(); } // return existing or narrowed proxy Object narrowed = persistenceContext.narrowProxy( proxy, persister, keyToLoad, impl ); return narrowed; } else if ( options.isAllowProxyCreation() ) { log.trace("creating new proxy for entity"); // return new uninitialized proxy proxy = persister.createProxy( event.getEntityId(), event.getSession() ); persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey(keyToLoad); persistenceContext.addProxy(keyToLoad, proxy); return proxy; } else { // return a newly loaded object return load(event, persister, keyToLoad, options); } } } } /** * If the class to be loaded has been configured with a cache, then lock * given id in that cache and then perform the load. * * @return The loaded entity * @throws HibernateException */ protected Object lockAndLoad( final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final Options options, final SessionImplementor source) throws HibernateException { CacheConcurrencyStrategy.SoftLock lock = null; final CacheKey ck; if ( persister.hasCache() ) { ck = new CacheKey( event.getEntityId(), persister.getIdentifierType(), persister.getRootEntityName(), source.getEntityMode() ); lock = persister.getCache().lock(ck, null ); } else { ck = null; } Object entity; try { entity = load(event, persister, keyToLoad, options); } finally { if ( persister.hasCache() ) { persister.getCache().release(ck, lock ); } } Object proxy = event.getSession().getPersistenceContext().proxyFor( persister, keyToLoad, entity ); if ( !options.isAllowProxyCreation() ) { //force initialization of the proxy (just to connect it to the already-loaded entity) Hibernate.initialize(proxy); } return proxy; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -