/** INTERNAL: Delete the reference objects. */
  public void preDelete(DeleteObjectQuery query) throws DatabaseException, OptimisticLockException {
    if (isForeignKeyRelationship()) {
      return;
    }

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

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

    // if privately-owned parts have their privately-owned sub-parts, delete them one by one;
    // else delete everything in one shot
    if (this.mustDeleteReferenceObjectsOneByOne()) {
      for (Object iter = cp.iteratorFor(objects); cp.hasNext(iter); ) {
        DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
        deleteQuery.setIsExecutionClone(true);
        deleteQuery.setObject(cp.next(iter, query.getSession()));
        deleteQuery.setCascadePolicy(query.getCascadePolicy());
        query.getSession().executeQuery(deleteQuery);
      }
      if (!query.getSession().isUnitOfWork()) {
        // This deletes any objects on the database, as the collection in memory may have been
        // changed.
        // This is not required for unit of work, as the update would have already deleted these
        // objects,
        // and the backup copy will include the same objects causing double deletes.
        this.deleteReferenceObjectsLeftOnDatabase(query);
      }
    } else {
      this.deleteAll(query);
    }
  }
  /** INTERNAL: Delete the reference objects. */
  @Override
  public void postDelete(DeleteObjectQuery query)
      throws DatabaseException, OptimisticLockException {
    if (!isForeignKeyRelationship()) {
      return;
    }

    if (!this.shouldObjectModifyCascadeToParts(query)) {
      return;
    }
    Object referenceObjects =
        this.getRealCollectionAttributeValueFromObject(query.getObject(), query.getSession());

    // if we have a custom delete all query, use it;
    // otherwise, delete the reference objects one by one
    if (this.hasCustomDeleteAllQuery()) {
      this.deleteAll(query, referenceObjects);
    } else {
      ContainerPolicy cp = this.getContainerPolicy();
      for (Object iter = cp.iteratorFor(referenceObjects); cp.hasNext(iter); ) {
        DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
        deleteQuery.setIsExecutionClone(true);
        deleteQuery.setObject(cp.next(iter, query.getSession()));
        deleteQuery.setCascadePolicy(query.getCascadePolicy());
        query.getSession().executeQuery(deleteQuery);
      }
      if (!query.getSession().isUnitOfWork()) {
        // This deletes any objects on the database, as the collection in memory may have been
        // changed.
        // This is not required for unit of work, as the update would have already deleted these
        // objects,
        // and the backup copy will include the same objects, causing double deletes.
        this.deleteReferenceObjectsLeftOnDatabase(query);
      }
    }
  }