Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » event » def » [javadoc | source]
    1   /*
    2    * Hibernate, Relational Persistence for Idiomatic Java
    3    *
    4    * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
    5    * indicated by the @author tags or express copyright attribution
    6    * statements applied by the authors.  All third-party contributions are
    7    * distributed under license by Red Hat Middleware LLC.
    8    *
    9    * This copyrighted material is made available to anyone wishing to use, modify,
   10    * copy, or redistribute it subject to the terms and conditions of the GNU
   11    * Lesser General Public License, as published by the Free Software Foundation.
   12    *
   13    * This program is distributed in the hope that it will be useful,
   14    * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   15    * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
   16    * for more details.
   17    *
   18    * You should have received a copy of the GNU Lesser General Public License
   19    * along with this distribution; if not, write to:
   20    * Free Software Foundation, Inc.
   21    * 51 Franklin Street, Fifth Floor
   22    * Boston, MA  02110-1301  USA
   23    *
   24    */
   25   package org.hibernate.event.def;
   26   
   27   import java.io.Serializable;
   28   
   29   import org.slf4j.Logger;
   30   import org.slf4j.LoggerFactory;
   31   import org.hibernate.HibernateException;
   32   import org.hibernate.LockMode;
   33   import org.hibernate.NonUniqueObjectException;
   34   import org.hibernate.PersistentObjectException;
   35   import org.hibernate.TypeMismatchException;
   36   import org.hibernate.EntityMode;
   37   import org.hibernate.cache.CacheKey;
   38   import org.hibernate.cache.access.SoftLock;
   39   import org.hibernate.cache.entry.CacheEntry;
   40   import org.hibernate.engine.EntityEntry;
   41   import org.hibernate.engine.EntityKey;
   42   import org.hibernate.engine.PersistenceContext;
   43   import org.hibernate.engine.SessionFactoryImplementor;
   44   import org.hibernate.engine.SessionImplementor;
   45   import org.hibernate.engine.Status;
   46   import org.hibernate.engine.TwoPhaseLoad;
   47   import org.hibernate.engine.Versioning;
   48   import org.hibernate.event.EventSource;
   49   import org.hibernate.event.LoadEvent;
   50   import org.hibernate.event.LoadEventListener;
   51   import org.hibernate.event.PostLoadEvent;
   52   import org.hibernate.event.PostLoadEventListener;
   53   import org.hibernate.persister.entity.EntityPersister;
   54   import org.hibernate.pretty.MessageHelper;
   55   import org.hibernate.proxy.HibernateProxy;
   56   import org.hibernate.proxy.LazyInitializer;
   57   import org.hibernate.type.Type;
   58   import org.hibernate.type.TypeFactory;
   59   
   60   /**
   61    * Defines the default load event listeners used by hibernate for loading entities
   62    * in response to generated load events.
   63    *
   64    * @author Steve Ebersole
   65    */
   66   public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener implements LoadEventListener {
   67   
   68   	public static final Object REMOVED_ENTITY_MARKER = new Object();
   69   	public static final Object INCONSISTENT_RTN_CLASS_MARKER = new Object();
   70   	public static final LockMode DEFAULT_LOCK_MODE = LockMode.NONE;
   71   
   72   	private static final Logger log = LoggerFactory.getLogger(DefaultLoadEventListener.class);
   73   
   74   
   75   	/**
   76   	 * Handle the given load event.
   77   	 *
   78   	 * @param event The load event to be handled.
   79   	 * @throws HibernateException
   80   	 */
   81   	public void onLoad(LoadEvent event, LoadEventListener.LoadType loadType) throws HibernateException {
   82   
   83   		final SessionImplementor source = event.getSession();
   84   
   85   		EntityPersister persister;
   86   		if ( event.getInstanceToLoad() != null ) {
   87   			persister = source.getEntityPersister( null, event.getInstanceToLoad() ); //the load() which takes an entity does not pass an entityName
   88   			event.setEntityClassName( event.getInstanceToLoad().getClass().getName() );
   89   		}
   90   		else {
   91   			persister = source.getFactory().getEntityPersister( event.getEntityClassName() );
   92   		}
   93   
   94   		if ( persister == null ) {
   95   			throw new HibernateException(
   96   					"Unable to locate persister: " +
   97   					event.getEntityClassName()
   98   				);
   99   		}
  100   
  101   		if ( persister.getIdentifierType().isComponentType() && EntityMode.DOM4J == event.getSession().getEntityMode() ) {
  102   			// skip this check for composite-ids relating to dom4j entity-mode;
  103   			// alternatively, we could add a check to make sure the incoming id value is
  104   			// an instance of Element...
  105   		}
  106   		else {
  107   			Class idClass = persister.getIdentifierType().getReturnedClass();
  108   			if ( idClass != null && ! idClass.isInstance( event.getEntityId() ) ) {
  109   				throw new TypeMismatchException(
  110   						"Provided id of the wrong type for class " + persister.getEntityName() + ". Expected: " + idClass + ", got " + event.getEntityId().getClass()
  111   				);
  112   			}
  113   		}
  114   
  115   		EntityKey keyToLoad = new EntityKey( event.getEntityId(), persister, source.getEntityMode()  );
  116   
  117   		try {
  118   			if ( loadType.isNakedEntityReturned() ) {
  119   				//do not return a proxy!
  120   				//(this option indicates we are initializing a proxy)
  121   				event.setResult( load(event, persister, keyToLoad, loadType) );
  122   			}
  123   			else {
  124   				//return a proxy if appropriate
  125   				if ( event.getLockMode() == LockMode.NONE ) {
  126   					event.setResult( proxyOrLoad(event, persister, keyToLoad, loadType) );
  127   				}
  128   				else {
  129   					event.setResult( lockAndLoad(event, persister, keyToLoad, loadType, source) );
  130   				}
  131   			}
  132   		}
  133   		catch(HibernateException e) {
  134   			log.info("Error performing load command", e);
  135   			throw e;
  136   		}
  137   	}
  138   
  139   	/**
  140   	 * Perfoms the load of an entity.
  141   	 *
  142   	 * @param event The initiating load request event
  143   	 * @param persister The persister corresponding to the entity to be loaded
  144   	 * @param keyToLoad The key of the entity to be loaded
  145   	 * @param options The defined load options
  146   	 * @return The loaded entity.
  147   	 * @throws HibernateException
  148   	 */
  149   	protected Object load(
  150   		final LoadEvent event,
  151   		final EntityPersister persister,
  152   		final EntityKey keyToLoad,
  153   		final LoadEventListener.LoadType options) {
  154   
  155   		if ( event.getInstanceToLoad() != null ) {
  156   			if ( event.getSession().getPersistenceContext().getEntry( event.getInstanceToLoad() ) != null ) {
  157   				throw new PersistentObjectException(
  158   						"attempted to load into an instance that was already associated with the session: " +
  159   						MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
  160   					);
  161   			}
  162   			persister.setIdentifier( event.getInstanceToLoad(), event.getEntityId(), event.getSession().getEntityMode() );
  163   		}
  164   
  165   		Object entity = doLoad(event, persister, keyToLoad, options);
  166   
  167   		boolean isOptionalInstance = event.getInstanceToLoad() != null;
  168   
  169   		if ( !options.isAllowNulls() || isOptionalInstance ) {
  170   			if ( entity == null ) {
  171   				event.getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( event.getEntityClassName(), event.getEntityId() );
  172   			}
  173   		}
  174   
  175   		if ( isOptionalInstance && entity != event.getInstanceToLoad() ) {
  176   			throw new NonUniqueObjectException( event.getEntityId(), event.getEntityClassName() );
  177   		}
  178   
  179   		return entity;
  180   	}
  181   
  182   	/**
  183   	 * Based on configured options, will either return a pre-existing proxy,
  184   	 * generate a new proxy, or perform an actual load.
  185   	 *
  186   	 * @param event The initiating load request event
  187   	 * @param persister The persister corresponding to the entity to be loaded
  188   	 * @param keyToLoad The key of the entity to be loaded
  189   	 * @param options The defined load options
  190   	 * @return The result of the proxy/load operation.
  191   	 */
  192   	protected Object proxyOrLoad(
  193   		final LoadEvent event,
  194   		final EntityPersister persister,
  195   		final EntityKey keyToLoad,
  196   		final LoadEventListener.LoadType options) {
  197   
  198   		if ( log.isTraceEnabled() ) {
  199   			log.trace(
  200   					"loading entity: " +
  201   					MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
  202   				);
  203   		}
  204   
  205   		if ( !persister.hasProxy() ) {
  206   			// this class has no proxies (so do a shortcut)
  207   			return load(event, persister, keyToLoad, options);
  208   		}
  209   		else {
  210   			final PersistenceContext persistenceContext = event.getSession().getPersistenceContext();
  211   
  212   			// look for a proxy
  213   			Object proxy = persistenceContext.getProxy(keyToLoad);
  214   			if ( proxy != null ) {
  215   				return returnNarrowedProxy( event, persister, keyToLoad, options, persistenceContext, proxy );
  216   			}
  217   			else {
  218   				if ( options.isAllowProxyCreation() ) {
  219   					return createProxyIfNecessary( event, persister, keyToLoad, options, persistenceContext );
  220   				}
  221   				else {
  222   					// return a newly loaded object
  223   					return load(event, persister, keyToLoad, options);
  224   				}
  225   			}
  226   
  227   		}
  228   	}
  229   
  230   	/**
  231   	 * Given a proxy, initialize it and/or narrow it provided either
  232   	 * is necessary.
  233   	 *
  234   	 * @param event The initiating load request event
  235   	 * @param persister The persister corresponding to the entity to be loaded
  236   	 * @param keyToLoad The key of the entity to be loaded
  237   	 * @param options The defined load options
  238   	 * @param persistenceContext The originating session
  239   	 * @param proxy The proxy to narrow
  240   	 * @return The created/existing proxy
  241   	 */
  242   	private Object returnNarrowedProxy(
  243   			final LoadEvent event,
  244   			final EntityPersister persister,
  245   			final EntityKey keyToLoad,
  246   			final LoadEventListener.LoadType options,
  247   			final PersistenceContext persistenceContext,
  248   			final Object proxy) {
  249   		log.trace("entity proxy found in session cache");
  250   		LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer();
  251   		if ( li.isUnwrap() ) {
  252   			return li.getImplementation();
  253   		}
  254   		Object impl = null;
  255   		if ( !options.isAllowProxyCreation() ) {
  256   			impl = load( event, persister, keyToLoad, options );
  257   			if ( impl == null ) {
  258   				event.getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( persister.getEntityName(), keyToLoad.getIdentifier());
  259   			}
  260   		}
  261   		return persistenceContext.narrowProxy( proxy, persister, keyToLoad, impl );
  262   	}
  263   
  264   	/**
  265   	 * If there is already a corresponding proxy associated with the
  266   	 * persistence context, return it; otherwise create a proxy, associate it
  267   	 * with the persistence context, and return the just-created proxy.
  268   	 *
  269   	 * @param event The initiating load request event
  270   	 * @param persister The persister corresponding to the entity to be loaded
  271   	 * @param keyToLoad The key of the entity to be loaded
  272   	 * @param options The defined load options
  273   	 * @param persistenceContext The originating session
  274   	 * @return The created/existing proxy
  275   	 */
  276   	private Object createProxyIfNecessary(
  277   			final LoadEvent event,
  278   			final EntityPersister persister,
  279   			final EntityKey keyToLoad,
  280   			final LoadEventListener.LoadType options,
  281   			final PersistenceContext persistenceContext) {
  282   		Object existing = persistenceContext.getEntity( keyToLoad );
  283   		if ( existing != null ) {
  284   			// return existing object or initialized proxy (unless deleted)
  285   			log.trace( "entity found in session cache" );
  286   			if ( options.isCheckDeleted() ) {
  287   				EntityEntry entry = persistenceContext.getEntry( existing );
  288   				Status status = entry.getStatus();
  289   				if ( status == Status.DELETED || status == Status.GONE ) {
  290   					return null;
  291   				}
  292   			}
  293   			return existing;
  294   		}
  295   		else {
  296   			log.trace( "creating new proxy for entity" );
  297   			// return new uninitialized proxy
  298   			Object proxy = persister.createProxy( event.getEntityId(), event.getSession() );
  299   			persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey(keyToLoad);
  300   			persistenceContext.addProxy(keyToLoad, proxy);
  301   			return proxy;
  302   		}
  303   	}
  304   
  305   	/**
  306   	 * If the class to be loaded has been configured with a cache, then lock
  307   	 * given id in that cache and then perform the load.
  308   	 *
  309   	 * @param event The initiating load request event
  310   	 * @param persister The persister corresponding to the entity to be loaded
  311   	 * @param keyToLoad The key of the entity to be loaded
  312   	 * @param options The defined load options
  313   	 * @param source The originating session
  314   	 * @return The loaded entity
  315   	 * @throws HibernateException
  316   	 */
  317   	protected Object lockAndLoad(
  318   			final LoadEvent event,
  319   			final EntityPersister persister,
  320   			final EntityKey keyToLoad,
  321   			final LoadEventListener.LoadType options,
  322   			final SessionImplementor source) {
  323   		SoftLock lock = null;
  324   		final CacheKey ck;
  325   		if ( persister.hasCache() ) {
  326   			ck = new CacheKey(
  327   					event.getEntityId(),
  328   					persister.getIdentifierType(),
  329   					persister.getRootEntityName(),
  330   					source.getEntityMode(),
  331   					source.getFactory()
  332   			);
  333   			lock = persister.getCacheAccessStrategy().lockItem( ck, null );
  334   		}
  335   		else {
  336   			ck = null;
  337   		}
  338   
  339   		Object entity;
  340   		try {
  341   			entity = load(event, persister, keyToLoad, options);
  342   		}
  343   		finally {
  344   			if ( persister.hasCache() ) {
  345   				persister.getCacheAccessStrategy().unlockItem( ck, lock );
  346   			}
  347   		}
  348   
  349   		return event.getSession().getPersistenceContext().proxyFor( persister, keyToLoad, entity );
  350   	}
  351   
  352   
  353   	/**
  354   	 * Coordinates the efforts to load a given entity.  First, an attempt is
  355   	 * made to load the entity from the session-level cache.  If not found there,
  356   	 * an attempt is made to locate it in second-level cache.  Lastly, an
  357   	 * attempt is made to load it directly from the datasource.
  358   	 *
  359   	 * @param event The load event
  360   	 * @param persister The persister for the entity being requested for load
  361   	 * @param keyToLoad The EntityKey representing the entity to be loaded.
  362   	 * @param options The load options.
  363   	 * @return The loaded entity, or null.
  364   	 */
  365   	protected Object doLoad(
  366   			final LoadEvent event,
  367   			final EntityPersister persister,
  368   			final EntityKey keyToLoad,
  369   			final LoadEventListener.LoadType options) {
  370   
  371   		if ( log.isTraceEnabled() ) {
  372   			log.trace(
  373   					"attempting to resolve: " +
  374   					MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
  375   				);
  376   		}
  377   
  378   		Object entity = loadFromSessionCache( event, keyToLoad, options );
  379   		if ( entity == REMOVED_ENTITY_MARKER ) {
  380   			log.debug( "load request found matching entity in context, but it is scheduled for removal; returning null" );
  381   			return null;
  382   		}
  383   		if ( entity == INCONSISTENT_RTN_CLASS_MARKER ) {
  384   			log.debug( "load request found matching entity in context, but the matched entity was of an inconsistent return type; returning null" );
  385   			return null;
  386   		}
  387   		if ( entity != null ) {
  388   			if ( log.isTraceEnabled() ) {
  389   				log.trace(
  390   						"resolved object in session cache: " +
  391   						MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory()  )
  392   					);
  393   			}
  394   			return entity;
  395   		}
  396   
  397   		entity = loadFromSecondLevelCache(event, persister, options);
  398   		if ( entity != null ) {
  399   			if ( log.isTraceEnabled() ) {
  400   				log.trace(
  401   						"resolved object in second-level cache: " +
  402   						MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
  403   					);
  404   			}
  405   			return entity;
  406   		}
  407   
  408   		if ( log.isTraceEnabled() ) {
  409   			log.trace(
  410   					"object not resolved in any cache: " +
  411   					MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
  412   				);
  413   		}
  414   
  415   		return loadFromDatasource(event, persister, keyToLoad, options);
  416   	}
  417   
  418   	/**
  419   	 * Performs the process of loading an entity from the configured
  420   	 * underlying datasource.
  421   	 *
  422   	 * @param event The load event
  423   	 * @param persister The persister for the entity being requested for load
  424   	 * @param keyToLoad The EntityKey representing the entity to be loaded.
  425   	 * @param options The load options.
  426   	 * @return The object loaded from the datasource, or null if not found.
  427   	 */
  428   	protected Object loadFromDatasource(
  429   			final LoadEvent event,
  430   			final EntityPersister persister,
  431   			final EntityKey keyToLoad,
  432   			final LoadEventListener.LoadType options) {
  433   		final SessionImplementor source = event.getSession();
  434   		Object entity = persister.load(
  435   				event.getEntityId(),
  436   				event.getInstanceToLoad(),
  437   				event.getLockMode(),
  438   				source
  439   		);
  440   
  441   		if ( event.isAssociationFetch() && source.getFactory().getStatistics().isStatisticsEnabled() ) {
  442   			source.getFactory().getStatisticsImplementor().fetchEntity( event.getEntityClassName() );
  443   		}
  444   
  445   		return entity;
  446   	}
  447   
  448   	/**
  449   	 * Attempts to locate the entity in the session-level cache.
  450   	 * <p/>
  451   	 * If allowed to return nulls, then if the entity happens to be found in
  452   	 * the session cache, we check the entity type for proper handling
  453   	 * of entity hierarchies.
  454   	 * <p/>
  455   	 * If checkDeleted was set to true, then if the entity is found in the
  456   	 * session-level cache, it's current status within the session cache
  457   	 * is checked to see if it has previously been scheduled for deletion.
  458   	 *
  459   	 * @param event The load event
  460   	 * @param keyToLoad The EntityKey representing the entity to be loaded.
  461   	 * @param options The load options.
  462   	 * @return The entity from the session-level cache, or null.
  463   	 * @throws HibernateException Generally indicates problems applying a lock-mode.
  464   	 */
  465   	protected Object loadFromSessionCache(
  466   			final LoadEvent event,
  467   			final EntityKey keyToLoad,
  468   			final LoadEventListener.LoadType options) throws HibernateException {
  469   
  470   		SessionImplementor session = event.getSession();
  471   		Object old = session.getEntityUsingInterceptor( keyToLoad );
  472   
  473   		if ( old != null ) {
  474   			// this object was already loaded
  475   			EntityEntry oldEntry = session.getPersistenceContext().getEntry( old );
  476   			if ( options.isCheckDeleted() ) {
  477   				Status status = oldEntry.getStatus();
  478   				if ( status == Status.DELETED || status == Status.GONE ) {
  479   					return REMOVED_ENTITY_MARKER;
  480   				}
  481   			}
  482   			if ( options.isAllowNulls() ) {
  483   				EntityPersister persister = event.getSession().getFactory().getEntityPersister( event.getEntityClassName() );
  484   				if ( ! persister.isInstance( old, event.getSession().getEntityMode() ) ) {
  485   					return INCONSISTENT_RTN_CLASS_MARKER;
  486   				}
  487   			}
  488   			upgradeLock( old, oldEntry, event.getLockMode(), session );
  489   		}
  490   
  491   		return old;
  492   	}
  493   
  494   	/**
  495   	 * Attempts to load the entity from the second-level cache.
  496   	 *
  497   	 * @param event The load event
  498   	 * @param persister The persister for the entity being requested for load
  499   	 * @param options The load options.
  500   	 * @return The entity from the second-level cache, or null.
  501   	 */
  502   	protected Object loadFromSecondLevelCache(
  503   			final LoadEvent event,
  504   			final EntityPersister persister,
  505   			final LoadEventListener.LoadType options) {
  506   
  507   		final SessionImplementor source = event.getSession();
  508   
  509   		final boolean useCache = persister.hasCache()
  510   				&& source.getCacheMode().isGetEnabled()
  511   				&& event.getLockMode().lessThan(LockMode.READ);
  512   
  513   		if ( useCache ) {
  514   
  515   			final SessionFactoryImplementor factory = source.getFactory();
  516   
  517   			final CacheKey ck = new CacheKey(
  518   					event.getEntityId(),
  519   					persister.getIdentifierType(),
  520   					persister.getRootEntityName(),
  521   					source.getEntityMode(),
  522   					source.getFactory()
  523   			);
  524   			Object ce = persister.getCacheAccessStrategy().get( ck, source.getTimestamp() );
  525   			if ( factory.getStatistics().isStatisticsEnabled() ) {
  526   				if ( ce == null ) {
  527   					factory.getStatisticsImplementor().secondLevelCacheMiss(
  528   							persister.getCacheAccessStrategy().getRegion().getName()
  529   					);
  530   				}
  531   				else {
  532   					factory.getStatisticsImplementor().secondLevelCacheHit(
  533   							persister.getCacheAccessStrategy().getRegion().getName()
  534   					);
  535   				}
  536   			}
  537   
  538   			if ( ce != null ) {
  539   				CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure().destructure( ce, factory );
  540   
  541   				// Entity was found in second-level cache...
  542   				return assembleCacheEntry(
  543   						entry,
  544   						event.getEntityId(),
  545   						persister,
  546   						event
  547   				);
  548   			}
  549   		}
  550   
  551   		return null;
  552   	}
  553   
  554   	private Object assembleCacheEntry(
  555   			final CacheEntry entry,
  556   			final Serializable id,
  557   			final EntityPersister persister,
  558   			final LoadEvent event) throws HibernateException {
  559   
  560   		final Object optionalObject = event.getInstanceToLoad();
  561   		final EventSource session = event.getSession();
  562   		final SessionFactoryImplementor factory = session.getFactory();
  563   
  564   		if ( log.isTraceEnabled() ) {
  565   			log.trace(
  566   					"assembling entity from second-level cache: " +
  567   					MessageHelper.infoString( persister, id, factory )
  568   				);
  569   		}
  570   
  571   		EntityPersister subclassPersister = factory.getEntityPersister( entry.getSubclass() );
  572   		Object result = optionalObject == null ?
  573   				session.instantiate( subclassPersister, id ) : optionalObject;
  574   
  575   		// make it circular-reference safe
  576   		TwoPhaseLoad.addUninitializedCachedEntity(
  577   				new EntityKey( id, subclassPersister, session.getEntityMode() ),
  578   				result,
  579   				subclassPersister,
  580   				LockMode.NONE,
  581   				entry.areLazyPropertiesUnfetched(),
  582   				entry.getVersion(),
  583   				session
  584   			);
  585   
  586   		Type[] types = subclassPersister.getPropertyTypes();
  587   		Object[] values = entry.assemble( result, id, subclassPersister, session.getInterceptor(), session ); // intializes result by side-effect
  588   		TypeFactory.deepCopy(
  589   				values,
  590   				types,
  591   				subclassPersister.getPropertyUpdateability(),
  592   				values,
  593   				session
  594   			);
  595   
  596   		Object version = Versioning.getVersion( values, subclassPersister );
  597   		if ( log.isTraceEnabled() ) log.trace( "Cached Version: " + version );
  598   
  599   		final PersistenceContext persistenceContext = session.getPersistenceContext();
  600   		persistenceContext.addEntry(
  601   				result,
  602   				Status.MANAGED,
  603   				values,
  604   				null,
  605   				id,
  606   				version,
  607   				LockMode.NONE,
  608   				true,
  609   				subclassPersister,
  610   				false,
  611   				entry.areLazyPropertiesUnfetched()
  612   			);
  613   		subclassPersister.afterInitialize( result, entry.areLazyPropertiesUnfetched(), session );
  614   		persistenceContext.initializeNonLazyCollections();
  615   		// upgrade the lock if necessary:
  616   		//lock(result, lockMode);
  617   
  618   		//PostLoad is needed for EJB3
  619   		//TODO: reuse the PostLoadEvent...
  620   		PostLoadEvent postLoadEvent = new PostLoadEvent(session).setEntity(result)
  621   				.setId(id).setPersister(persister);
  622   		PostLoadEventListener[] listeners = session.getListeners().getPostLoadEventListeners();
  623   		for ( int i = 0; i < listeners.length; i++ ) {
  624   			listeners[i].onPostLoad(postLoadEvent);
  625   		}
  626   
  627   		return result;
  628   	}
  629   
  630   }

Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » event » def » [javadoc | source]