/** * 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); } } } }
/** * 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; }
/** * Attempts to locate the entity in the session-level cache. If checkDeleted was set to true, then * if the entity is found in the session-level cache, it's current status within the session cache * is checked to see if it has previously been scheduled for deletion. * * @return The entity from the session-level cache, or null. * @throws HibernateException */ protected Object loadFromSessionCache( final LoadEvent event, final EntityKey keyToLoad, final LoadEventListener.LoadType options) throws HibernateException { SessionImplementor session = event.getSession(); Object old = session.getEntityUsingInterceptor(keyToLoad); if (old != null) { // this object was already loaded EntityEntry oldEntry = session.getPersistenceContext().getEntry(old); if (options.isCheckDeleted()) { throwObjectDeletedIfNecessary(event, oldEntry); } upgradeLock(old, oldEntry, event.getLockMode(), session); } return old; }
/** 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"); LazyInitializer li = ((HibernateProxy) proxy).getHibernateLazyInitializer(); if (li.isUnwrap()) { return li.getImplementation(); } // return existing or narrowed proxy Object impl = options.isAllowProxyCreation() ? null : load(event, persister, keyToLoad, options); return persistenceContext.narrowProxy(proxy, persister, keyToLoad, impl); }
/** * Handle the given load event. * * @param event The load event to be handled. * @return The result (i.e., the loaded entity). * @throws HibernateException */ public void 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 indicates we are initializing a proxy) event.setResult(load(event, persister, keyToLoad, loadType)); } else { // return a proxy if appropriate if (event.getLockMode() == LockMode.NONE) { event.setResult(proxyOrLoad(event, persister, keyToLoad, loadType)); } else { event.setResult(lockAndLoad(event, persister, keyToLoad, loadType, source)); } } } catch (HibernateException e) { log.info("Error performing load command", e); throw e; } }
/** * 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; } }