/**
   * Attempts to load the entity from the second-level cache.
   *
   * @return The entity from the second-level cache, or null.
   * @throws HibernateException
   */
  protected Object loadFromSecondLevelCache(
      final LoadEvent event,
      final EntityPersister persister,
      final LoadEventListener.LoadType options)
      throws HibernateException {

    final SessionImplementor source = event.getSession();

    final boolean useCache =
        persister.hasCache()
            && source.getCacheMode().isGetEnabled()
            && event.getLockMode().lessThan(LockMode.READ);

    if (useCache) {

      final SessionFactoryImplementor factory = source.getFactory();

      final CacheKey ck =
          new CacheKey(
              event.getEntityId(),
              persister.getIdentifierType(),
              persister.getRootEntityName(),
              source.getEntityMode(),
              source.getFactory());
      Object ce = persister.getCache().get(ck, source.getTimestamp());

      if (factory.getStatistics().isStatisticsEnabled()) {
        if (ce == null) {
          factory
              .getStatisticsImplementor()
              .secondLevelCacheMiss(persister.getCache().getRegionName());
        } else {
          factory
              .getStatisticsImplementor()
              .secondLevelCacheHit(persister.getCache().getRegionName());
        }
      }

      if (ce != null) {

        CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure().destructure(ce, factory);

        // Entity was found in second-level cache...
        return assembleCacheEntry(entry, event.getEntityId(), persister, event);
      }
    }

    return null;
  }
  /**
   * 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;
  }
  /**
   * 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;
    }
  }
  /**
   * Performs the process of loading an entity from the configured underlying datasource.
   *
   * @return The object loaded from the datasource, or null if not found.
   * @throws HibernateException
   */
  protected Object loadFromDatasource(
      final LoadEvent event,
      final EntityPersister persister,
      final EntityKey keyToLoad,
      final LoadEventListener.LoadType options)
      throws HibernateException {

    final SessionImplementor source = event.getSession();

    Object entity =
        persister.load(event.getEntityId(), event.getInstanceToLoad(), event.getLockMode(), source);

    /*if ( entity == null ) {
    	//remember it doesn't exist, in case of next time
    	source.getPersistenceContext().addNonExistantEntityKey(keyToLoad);
    }*/

    if (event.isAssociationFetch() && source.getFactory().getStatistics().isStatisticsEnabled()) {
      source.getFactory().getStatisticsImplementor().fetchEntity(event.getEntityClassName());
    }

    return entity;
  }