@Override
  public void initializeObjects(
      List<EntityInfo> entityInfos,
      LinkedHashMap<EntityInfoLoadKey, Object> idToObjectMap,
      ObjectInitializationContext objectInitializationContext) {
    // Do not call isTimeOut here as the caller might be the last biggie on the list.
    final int numberOfObjectsToInitialize = entityInfos.size();

    if (numberOfObjectsToInitialize == 0) {
      if (log.isTraceEnabled()) {
        log.tracef("No object to initialize");
      }
      return;
    }

    SessionImplementor sessionImplementor =
        (SessionImplementor) objectInitializationContext.getSession();
    String entityName =
        objectInitializationContext
            .getSession()
            .getSessionFactory()
            .getClassMetadata(objectInitializationContext.getEntityType())
            .getEntityName();
    EntityPersister persister = sessionImplementor.getFactory().getEntityPersister(entityName);
    PersistenceContext persistenceContext = sessionImplementor.getPersistenceContext();

    // check the persistence context
    List<EntityInfo> remainingEntityInfos = new ArrayList<>(numberOfObjectsToInitialize);
    for (EntityInfo entityInfo : entityInfos) {
      if (ObjectLoaderHelper.areDocIdAndEntityIdIdentical(
          entityInfo, objectInitializationContext.getSession())) {
        EntityKey entityKey = sessionImplementor.generateEntityKey(entityInfo.getId(), persister);
        Object o = persistenceContext.getEntity(entityKey);
        if (o == null) {
          remainingEntityInfos.add(entityInfo);
        } else {
          EntityInfoLoadKey key = new EntityInfoLoadKey(entityInfo.getClazz(), entityInfo.getId());
          idToObjectMap.put(key, o);
        }
      } else {
        // if document id !=  entity id we can't use PC lookup
        remainingEntityInfos.add(entityInfo);
      }
    }

    // update entityInfos to only contains the remaining ones
    final int remainingSize = remainingEntityInfos.size();
    if (log.isTraceEnabled()) {
      log.tracef(
          "Initialized %d objects out of %d in the persistence context",
          (Integer) (numberOfObjectsToInitialize - remainingSize),
          (Integer) numberOfObjectsToInitialize);
    }

    if (remainingSize > 0) {
      delegate.initializeObjects(remainingEntityInfos, idToObjectMap, objectInitializationContext);
    }
  }
예제 #2
0
  private static void processDereferencedCollection(
      PersistentCollection coll, SessionImplementor session) {
    final PersistenceContext persistenceContext = session.getPersistenceContext();
    CollectionEntry entry = persistenceContext.getCollectionEntry(coll);
    final CollectionPersister loadedPersister = entry.getLoadedPersister();

    if (LOG.isDebugEnabled() && loadedPersister != null) {
      LOG.debugf(
          "Collection dereferenced: %s",
          MessageHelper.collectionInfoString(
              loadedPersister, entry.getLoadedKey(), session.getFactory()));
    }

    // do a check
    boolean hasOrphanDelete = loadedPersister != null && loadedPersister.hasOrphanDelete();
    if (hasOrphanDelete) {
      Serializable ownerId =
          loadedPersister.getOwnerEntityPersister().getIdentifier(coll.getOwner(), session);
      if (ownerId == null) {
        // the owning entity may have been deleted and its identifier unset due to
        // identifier-rollback; in which case, try to look up its identifier from
        // the persistence context
        if (session.getFactory().getSettings().isIdentifierRollbackEnabled()) {
          EntityEntry ownerEntry = persistenceContext.getEntry(coll.getOwner());
          if (ownerEntry != null) {
            ownerId = ownerEntry.getId();
          }
        }
        if (ownerId == null) {
          throw new AssertionFailure(
              "Unable to determine collection owner identifier for orphan-delete processing");
        }
      }
      EntityKey key = session.generateEntityKey(ownerId, loadedPersister.getOwnerEntityPersister());
      Object owner = persistenceContext.getEntity(key);
      if (owner == null) {
        throw new AssertionFailure(
            "collection owner not associated with session: " + loadedPersister.getRole());
      }
      EntityEntry e = persistenceContext.getEntry(owner);
      // only collections belonging to deleted entities are allowed to be dereferenced in the case
      // of orphan delete
      if (e != null && e.getStatus() != Status.DELETED && e.getStatus() != Status.GONE) {
        throw new HibernateException(
            "A collection with cascade=\"all-delete-orphan\" was no longer referenced by the owning entity instance: "
                + loadedPersister.getRole());
      }
    }

    // do the work
    entry.setCurrentPersister(null);
    entry.setCurrentKey(null);
    prepareCollectionForUpdate(coll, entry, session.getFactory());
  }