/** Search the persistence context for an index of the child object, given a collection role */
  public Object getIndexInOwner(String entity, String property, Object childEntity, Map mergeMap) {

    EntityPersister persister = session.getFactory().getEntityPersister(entity);
    CollectionPersister cp = session.getFactory().getCollectionPersister(entity + '.' + property);
    Iterator entities = entityEntries.entrySet().iterator();
    while (entities.hasNext()) {
      Map.Entry me = (Map.Entry) entities.next();
      EntityEntry ee = (EntityEntry) me.getValue();
      if (persister.isSubclassEntityName(ee.getEntityName())) {
        Object instance = me.getKey();

        Object index = getIndexInParent(property, childEntity, persister, cp, instance);

        if (index == null && mergeMap != null) {
          Object unmergedInstance = mergeMap.get(instance);
          Object unmergedChild = mergeMap.get(childEntity);
          if (unmergedInstance != null && unmergedChild != null) {
            index = getIndexInParent(property, unmergedChild, persister, cp, unmergedInstance);
          }
        }

        if (index != null) return index;
      }
    }
    return null;
  }
 private static boolean useMinimalPuts(SessionImplementor session, EntityEntry entityEntry) {
   return (session.getFactory().getSettings().isMinimalPutsEnabled()
           && session.getCacheMode() != CacheMode.REFRESH)
       || (entityEntry.getPersister().hasLazyProperties()
           && entityEntry.isLoadedWithLazyPropertiesUnfetched()
           && entityEntry.getPersister().isLazyPropertiesCacheable());
 }
  /**
   * Search the persistence context for an owner for the child object, given a collection role. If
   * <tt>mergeMap</tt> is non-null, also check the detached graph being merged for a parent.
   */
  public Serializable getOwnerId(String entity, String property, Object childEntity, Map mergeMap) {

    EntityPersister persister = session.getFactory().getEntityPersister(entity);
    final CollectionPersister collectionPersister =
        session.getFactory().getCollectionPersister(entity + '.' + property);

    Iterator entities = entityEntries.entrySet().iterator();
    while (entities.hasNext()) {
      Map.Entry me = (Map.Entry) entities.next();
      EntityEntry ee = (EntityEntry) me.getValue();
      if (persister.isSubclassEntityName(ee.getEntityName())) {
        Object instance = me.getKey();

        // check if the managed object is the parent
        boolean found =
            isFoundInParent(property, childEntity, persister, collectionPersister, instance);

        if (!found && mergeMap != null) {
          // check if the detached object being merged is the parent
          Object unmergedInstance = mergeMap.get(instance);
          Object unmergedChild = mergeMap.get(childEntity);
          if (unmergedInstance != null && unmergedChild != null) {
            found =
                isFoundInParent(
                    property, unmergedChild, persister, collectionPersister, unmergedInstance);
          }
        }

        if (found) {
          return ee.getId();
        }
      }
    }
    return null;
  }
 public void setReadOnly(Object entity, boolean readOnly) {
   EntityEntry entry = getEntry(entity);
   if (entry == null) {
     throw new TransientObjectException("Instance was not associated with the session");
   }
   entry.setReadOnly(readOnly, entity);
   hasNonReadOnlyEntities = hasNonReadOnlyEntities || !readOnly;
 }
 private boolean isInManagedState(Object child, EventSource session) {
   EntityEntry entry = session.getPersistenceContext().getEntry(child);
   return entry != null
       && (entry.getStatus() == Status.MANAGED || entry.getStatus() == Status.READ_ONLY);
 }
 /**
  * Return the existing proxy associated with the given <tt>EntityKey</tt>, or the argument (the
  * entity associated with the key) if no proxy exists. (slower than the form above)
  */
 public Object proxyFor(Object impl) throws HibernateException {
   EntityEntry e = getEntry(impl);
   EntityPersister p = e.getPersister();
   return proxyFor(p, new EntityKey(e.getId(), p, session.getEntityMode()), impl);
 }
 public void setEntryStatus(EntityEntry entry, Status status) {
   entry.setStatus(status);
   setHasNonReadOnlyEnties(status);
 }
  public static StatefulPersistenceContext deserialize(
      ObjectInputStream ois, SessionImplementor session)
      throws IOException, ClassNotFoundException {
    log.trace("deserializing persistent-context");
    StatefulPersistenceContext rtn = new StatefulPersistenceContext(session);

    // during deserialization, we need to reconnect all proxies and
    // collections to this session, as well as the EntityEntry and
    // CollectionEntry instances; these associations are transient
    // because serialization is used for different things.

    try {
      // todo : we can actually just determine this from the incoming EntityEntry-s
      rtn.hasNonReadOnlyEntities = ois.readBoolean();

      int count = ois.readInt();
      log.trace("staring deserialization of [" + count + "] entitiesByKey entries");
      rtn.entitiesByKey = new HashMap(count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count);
      for (int i = 0; i < count; i++) {
        rtn.entitiesByKey.put(EntityKey.deserialize(ois, session), ois.readObject());
      }

      count = ois.readInt();
      log.trace("staring deserialization of [" + count + "] entitiesByUniqueKey entries");
      rtn.entitiesByUniqueKey = new HashMap(count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count);
      for (int i = 0; i < count; i++) {
        rtn.entitiesByUniqueKey.put(EntityUniqueKey.deserialize(ois, session), ois.readObject());
      }

      count = ois.readInt();
      log.trace("staring deserialization of [" + count + "] proxiesByKey entries");
      rtn.proxiesByKey =
          new ReferenceMap(
              ReferenceMap.HARD,
              ReferenceMap.WEAK,
              count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count,
              .75f);
      for (int i = 0; i < count; i++) {
        EntityKey ek = EntityKey.deserialize(ois, session);
        Object proxy = ois.readObject();
        if (proxy instanceof HibernateProxy) {
          ((HibernateProxy) proxy).getHibernateLazyInitializer().setSession(session);
          rtn.proxiesByKey.put(ek, proxy);
        } else {
          log.trace("encountered prunded proxy");
        }
        // otherwise, the proxy was pruned during the serialization process
      }

      count = ois.readInt();
      log.trace("staring deserialization of [" + count + "] entitySnapshotsByKey entries");
      rtn.entitySnapshotsByKey = new HashMap(count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count);
      for (int i = 0; i < count; i++) {
        rtn.entitySnapshotsByKey.put(EntityKey.deserialize(ois, session), ois.readObject());
      }

      count = ois.readInt();
      log.trace("staring deserialization of [" + count + "] entityEntries entries");
      rtn.entityEntries =
          IdentityMap.instantiateSequenced(count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count);
      for (int i = 0; i < count; i++) {
        Object entity = ois.readObject();
        EntityEntry entry = EntityEntry.deserialize(ois, session);
        rtn.entityEntries.put(entity, entry);
      }

      count = ois.readInt();
      log.trace("staring deserialization of [" + count + "] collectionsByKey entries");
      rtn.collectionsByKey = new HashMap(count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count);
      for (int i = 0; i < count; i++) {
        rtn.collectionsByKey.put(CollectionKey.deserialize(ois, session), ois.readObject());
      }

      count = ois.readInt();
      log.trace("staring deserialization of [" + count + "] collectionEntries entries");
      rtn.collectionEntries =
          IdentityMap.instantiateSequenced(count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count);
      for (int i = 0; i < count; i++) {
        final PersistentCollection pc = (PersistentCollection) ois.readObject();
        final CollectionEntry ce = CollectionEntry.deserialize(ois, session);
        pc.setCurrentSession(session);
        rtn.collectionEntries.put(pc, ce);
      }

      count = ois.readInt();
      log.trace("staring deserialization of [" + count + "] arrayHolders entries");
      rtn.arrayHolders = IdentityMap.instantiate(count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count);
      for (int i = 0; i < count; i++) {
        rtn.arrayHolders.put(ois.readObject(), ois.readObject());
      }

      count = ois.readInt();
      log.trace("staring deserialization of [" + count + "] nullifiableEntityKeys entries");
      rtn.nullifiableEntityKeys = new HashSet();
      for (int i = 0; i < count; i++) {
        rtn.nullifiableEntityKeys.add(EntityKey.deserialize(ois, session));
      }

    } catch (HibernateException he) {
      throw new InvalidObjectException(he.getMessage());
    }

    return rtn;
  }
  public void replaceDelayedEntityIdentityInsertKeys(EntityKey oldKey, Serializable generatedId) {
    Object entity = entitiesByKey.remove(oldKey);
    EntityEntry oldEntry = (EntityEntry) entityEntries.remove(entity);

    EntityKey newKey =
        new EntityKey(generatedId, oldEntry.getPersister(), getSession().getEntityMode());
    addEntity(newKey, entity);
    addEntry(
        entity,
        oldEntry.getStatus(),
        oldEntry.getLoadedState(),
        oldEntry.getRowId(),
        generatedId,
        oldEntry.getVersion(),
        oldEntry.getLockMode(),
        oldEntry.isExistsInDatabase(),
        oldEntry.getPersister(),
        oldEntry.isBeingReplicated(),
        oldEntry.isLoadedWithLazyPropertiesUnfetched());
  }
  /**
   * Perform the second step of 2-phase load. Fully initialize the entity instance.
   *
   * <p>After processing a JDBC result set, we "resolve" all the associations between the entities
   * which were instantiated and had their state "hydrated" into an array
   */
  public static void initializeEntity(
      final Object entity,
      final boolean readOnly,
      final SessionImplementor session,
      final PreLoadEvent preLoadEvent,
      final PostLoadEvent postLoadEvent)
      throws HibernateException {

    // TODO: Should this be an InitializeEntityEventListener??? (watch out for performance!)

    final PersistenceContext persistenceContext = session.getPersistenceContext();
    EntityEntry entityEntry = persistenceContext.getEntry(entity);
    if (entityEntry == null) {
      throw new AssertionFailure("possible non-threadsafe access to the session");
    }
    EntityPersister persister = entityEntry.getPersister();
    Serializable id = entityEntry.getId();
    Object[] hydratedState = entityEntry.getLoadedState();

    if (log.isDebugEnabled())
      log.debug(
          "resolving associations for "
              + MessageHelper.infoString(persister, id, session.getFactory()));

    Type[] types = persister.getPropertyTypes();
    for (int i = 0; i < hydratedState.length; i++) {
      final Object value = hydratedState[i];
      if (value != LazyPropertyInitializer.UNFETCHED_PROPERTY
          && value != BackrefPropertyAccessor.UNKNOWN) {
        hydratedState[i] = types[i].resolve(value, session, entity);
      }
    }

    // Must occur after resolving identifiers!
    if (session.isEventSource()) {
      preLoadEvent.setEntity(entity).setState(hydratedState).setId(id).setPersister(persister);
      PreLoadEventListener[] listeners = session.getListeners().getPreLoadEventListeners();
      for (int i = 0; i < listeners.length; i++) {
        listeners[i].onPreLoad(preLoadEvent);
      }
    }

    persister.setPropertyValues(entity, hydratedState, session.getEntityMode());

    final SessionFactoryImplementor factory = session.getFactory();
    if (persister.hasCache() && session.getCacheMode().isPutEnabled()) {

      if (log.isDebugEnabled())
        log.debug(
            "adding entity to second-level cache: "
                + MessageHelper.infoString(persister, id, session.getFactory()));

      Object version = Versioning.getVersion(hydratedState, persister);
      CacheEntry entry =
          new CacheEntry(
              hydratedState,
              persister,
              entityEntry.isLoadedWithLazyPropertiesUnfetched(),
              version,
              session,
              entity);
      CacheKey cacheKey =
          new CacheKey(
              id,
              persister.getIdentifierType(),
              persister.getRootEntityName(),
              session.getEntityMode(),
              session.getFactory());
      boolean put =
          persister
              .getCache()
              .put(
                  cacheKey,
                  persister.getCacheEntryStructure().structure(entry),
                  session.getTimestamp(),
                  version,
                  persister.isVersioned() ? persister.getVersionType().getComparator() : null,
                  useMinimalPuts(
                      session,
                      entityEntry)); // we could use persister.hasLazyProperties() instead of true

      if (put && factory.getStatistics().isStatisticsEnabled()) {
        factory
            .getStatisticsImplementor()
            .secondLevelCachePut(persister.getCache().getRegionName());
      }
    }

    if (readOnly || !persister.isMutable()) {
      // no need to take a snapshot - this is a
      // performance optimization, but not really
      // important, except for entities with huge
      // mutable property values
      persistenceContext.setEntryStatus(entityEntry, Status.READ_ONLY);
    } else {
      // take a snapshot
      TypeFactory.deepCopy(
          hydratedState,
          persister.getPropertyTypes(),
          persister.getPropertyUpdateability(),
          hydratedState, // after setting values to object, entityMode
          session);
      persistenceContext.setEntryStatus(entityEntry, Status.MANAGED);
    }

    persister.afterInitialize(entity, entityEntry.isLoadedWithLazyPropertiesUnfetched(), session);

    if (session.isEventSource()) {
      postLoadEvent.setEntity(entity).setId(id).setPersister(persister);
      PostLoadEventListener[] listeners = session.getListeners().getPostLoadEventListeners();
      for (int i = 0; i < listeners.length; i++) {
        listeners[i].onPostLoad(postLoadEvent);
      }
    }

    if (log.isDebugEnabled())
      log.debug(
          "done materializing entity "
              + MessageHelper.infoString(persister, id, session.getFactory()));

    if (factory.getStatistics().isStatisticsEnabled()) {
      factory.getStatisticsImplementor().loadEntity(persister.getEntityName());
    }
  }