/**
   * 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;
  }
 public <A> A find(
     Class<A> entityClass,
     Object primaryKey,
     LockModeType lockModeType,
     Map<String, Object> properties) {
   CacheMode previousCacheMode = getSession().getCacheMode();
   CacheMode cacheMode = determineAppropriateLocalCacheMode(properties);
   LockOptions lockOptions = null;
   try {
     getSession().setCacheMode(cacheMode);
     if (lockModeType != null) {
       return (A)
           getSession()
               .get(
                   entityClass,
                   (Serializable) primaryKey,
                   getLockRequest(lockModeType, properties));
     } else {
       return (A) getSession().get(entityClass, (Serializable) primaryKey);
     }
   } catch (ObjectDeletedException e) {
     // the spec is silent about people doing remove() find() on the same PC
     return null;
   } catch (ObjectNotFoundException e) {
     // should not happen on the entity itself with get
     throw new IllegalArgumentException(e.getMessage(), e);
   } catch (MappingException e) {
     throw new IllegalArgumentException(e.getMessage(), e);
   } catch (TypeMismatchException e) {
     throw new IllegalArgumentException(e.getMessage(), e);
   } catch (ClassCastException e) {
     throw new IllegalArgumentException(e.getMessage(), e);
   } catch (HibernateException he) {
     throw convert(he, lockOptions);
   } finally {
     getSession().setCacheMode(previousCacheMode);
   }
 }