📄 defaultloadeventlistener.java
字号:
//$Id: DefaultLoadEventListener.java,v 1.12 2005/05/11 22:15:05 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.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.SessionImplementor;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.persister.entity.EntityPersister;import org.hibernate.pretty.MessageHelper;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() ); } EntityKey keyToLoad = new EntityKey( event.getEntityId(), persister, source.getEntityMode() ); try { if ( loadType.isNakedEntityReturned() ) { //do not return a proxy! //(this option inidicates we are initializing a proxy) return load(event, persister, keyToLoad, loadType); } else { //return a proxy if appropriate return event.getLockMode() == LockMode.NONE ? proxyOrLoad(event, persister, keyToLoad, loadType) : lockAndLoad(event, persister, keyToLoad, loadType, source); } } catch(HibernateException e) { log.info("Error performing load command", e); throw e; } } /** * 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 LoadEventListener.LoadType options) 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); 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 LoadEventListener.LoadType 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 { final PersistenceContext persistenceContext = event.getSession().getPersistenceContext(); // look for a proxy Object proxy = persistenceContext.getProxy(keyToLoad); if ( proxy != null ) { return returnNarrowedProxy( event, persister, keyToLoad, options, persistenceContext, proxy ); } else { if ( options.isAllowProxyCreation() ) { return createProxyIfNecessary( event, persister, keyToLoad, options, persistenceContext ); } else { // return a newly loaded object return load(event, persister, keyToLoad, options); } } } } /** * Given that there is a pre-existing proxy. * Initialize it if necessary; narrow if necessary. */ private Object returnNarrowedProxy( final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final LoadEventListener.LoadType options, final PersistenceContext persistenceContext, final Object proxy ) { log.trace("entity proxy found in session cache"); // return existing or narrowed proxy Object impl = options.isAllowProxyCreation() ? null : load(event, persister, keyToLoad, options); return persistenceContext.narrowProxy( proxy, persister, keyToLoad, impl ); } /** * Given that there is no pre-existing proxy. * Check if the entity is already loaded. If it is, return the entity, * otherwise create and return a proxy. */ private Object createProxyIfNecessary( final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final LoadEventListener.LoadType options, final PersistenceContext persistenceContext ) { 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); throwObjectDeletedIfNecessary(event, entry); } 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; } } /** * 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 LoadEventListener.LoadType 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(), source.getFactory() ); 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 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -