/** INTERNAL: Insert privately owned parts */
  public void preInsert(WriteObjectQuery query) throws DatabaseException, OptimisticLockException {
    if (!this.isForeignKeyRelationship()) {
      return;
    }

    if (!this.shouldObjectModifyCascadeToParts(query)) {
      return;
    }

    // only cascade dependents in UOW
    if (query.shouldCascadeOnlyDependentParts()) {
      return;
    }

    Object objects =
        this.getRealCollectionAttributeValueFromObject(query.getObject(), query.getSession());

    // insert each object one by one
    ContainerPolicy cp = this.getContainerPolicy();
    for (Object iter = cp.iteratorFor(objects); cp.hasNext(iter); ) {
      Object object = cp.next(iter, query.getSession());
      if (this.isPrivateOwned()) {
        // no need to set changeset here as insert is just a copy of the object anyway
        InsertObjectQuery insertQuery = new InsertObjectQuery();
        insertQuery.setIsExecutionClone(true);
        insertQuery.setObject(object);
        insertQuery.setCascadePolicy(query.getCascadePolicy());
        query.getSession().executeQuery(insertQuery);
      } else {
        // This will happen in a unit of work or cascaded query.
        // This is done only for persistence by reachability and is not required if the targets are
        // in the queue anyway
        // Avoid cycles by checking commit manager, this is allowed because there is no dependency.
        if (!query.getSession().getCommitManager().isCommitInPreModify(object)) {
          WriteObjectQuery writeQuery = new WriteObjectQuery();
          writeQuery.setIsExecutionClone(true);
          if (query.getSession().isUnitOfWork()) {
            UnitOfWorkChangeSet uowChangeSet =
                (UnitOfWorkChangeSet)
                    ((UnitOfWorkImpl) query.getSession()).getUnitOfWorkChangeSet();
            if (uowChangeSet != null) {
              writeQuery.setObjectChangeSet(
                  (ObjectChangeSet) uowChangeSet.getObjectChangeSetForClone(object));
            }
          }
          writeQuery.setObject(object);
          writeQuery.setCascadePolicy(query.getCascadePolicy());
          query.getSession().executeQuery(writeQuery);
        }
      }
    }
  }