/** INTERNAL: Update privately owned parts */
  public void preUpdate(WriteObjectQuery query) throws DatabaseException, OptimisticLockException {
    if (!isAttributeValueInstantiated(query.getObject())) {
      return;
    }

    if (isPrivateOwned()) {
      Object objectInDatabase = readPrivateOwnedForObject(query);
      if (objectInDatabase != null) {
        query.setProperty(this, objectInDatabase);
      }
    }

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

    // Get the privately owned parts in the memory
    Object object = getRealAttributeValueFromObject(query.getObject(), query.getSession());
    if (object != null) {
      ObjectChangeSet changeSet = null;
      UnitOfWorkChangeSet uowChangeSet = null;
      if (query.getSession().isUnitOfWork()
          && (((UnitOfWorkImpl) query.getSession()).getUnitOfWorkChangeSet() != null)) {
        uowChangeSet =
            (UnitOfWorkChangeSet) ((UnitOfWorkImpl) query.getSession()).getUnitOfWorkChangeSet();
        changeSet = (ObjectChangeSet) uowChangeSet.getObjectChangeSetForClone(object);
      }
      WriteObjectQuery writeQuery = new WriteObjectQuery();
      writeQuery.setIsExecutionClone(true);
      writeQuery.setObject(object);
      writeQuery.setObjectChangeSet(changeSet);
      writeQuery.setCascadePolicy(query.getCascadePolicy());
      query.getSession().executeQuery(writeQuery);
    }
  }
  /** INTERNAL: Insert privately owned parts */
  public void preInsert(WriteObjectQuery query) throws DatabaseException, OptimisticLockException {
    // Checks if privately owned parts should be inserted or not.
    if (!shouldObjectModifyCascadeToParts(query)) {
      return;
    }

    // Get the privately owned parts
    Object object = getRealAttributeValueFromObject(query.getObject(), query.getSession());

    if (object == null) {
      return;
    }

    if (isPrivateOwned()) {
      // No need to set changeSet as insert is a straight copy anyway
      InsertObjectQuery insertQuery = new InsertObjectQuery();
      insertQuery.setIsExecutionClone(true);
      insertQuery.setObject(object);
      insertQuery.setCascadePolicy(query.getCascadePolicy());
      query.getSession().executeQuery(insertQuery);
    } else {
      ObjectChangeSet changeSet = null;
      UnitOfWorkChangeSet uowChangeSet = null;
      if (query.getSession().isUnitOfWork()
          && (((UnitOfWorkImpl) query.getSession()).getUnitOfWorkChangeSet() != null)) {
        uowChangeSet =
            (UnitOfWorkChangeSet) ((UnitOfWorkImpl) query.getSession()).getUnitOfWorkChangeSet();
        changeSet = (ObjectChangeSet) uowChangeSet.getObjectChangeSetForClone(object);
      }
      WriteObjectQuery writeQuery = new WriteObjectQuery();
      writeQuery.setIsExecutionClone(true);
      writeQuery.setObject(object);
      writeQuery.setObjectChangeSet(changeSet);
      writeQuery.setCascadePolicy(query.getCascadePolicy());
      query.getSession().executeQuery(writeQuery);
    }
  }