/** 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);
    }
  }
 /**
  * Commit all of the objects of the class type in the change set. This allows for the order of the
  * classes to be processed optimally.
  */
 protected void commitNewObjectsForClassWithChangeSet(
     UnitOfWorkChangeSet uowChangeSet, Class theClass) {
   Map<ObjectChangeSet, ObjectChangeSet> newObjectChangesList =
       uowChangeSet.getNewObjectChangeSets().get(theClass);
   if (newObjectChangesList != null) { // may be no changes for that class type.
     AbstractSession session = getSession();
     ClassDescriptor descriptor = session.getDescriptor(theClass);
     List<ObjectChangeSet> newChangeSets = new ArrayList(newObjectChangesList.values());
     int size = newChangeSets.size();
     for (int index = 0; index < size; index++) {
       ObjectChangeSet changeSetToWrite = newChangeSets.get(index);
       Object objectToWrite = changeSetToWrite.getUnitOfWorkClone();
       if (!isProcessedCommit(objectToWrite)) {
         // PERF: Get the descriptor query, to avoid extra query creation.
         InsertObjectQuery commitQuery = descriptor.getQueryManager().getInsertQuery();
         if (commitQuery == null) {
           commitQuery = new InsertObjectQuery();
           commitQuery.setDescriptor(descriptor);
         } else {
           // Ensure original query has been prepared.
           commitQuery.checkPrepare(session, commitQuery.getTranslationRow());
           commitQuery = (InsertObjectQuery) commitQuery.clone();
         }
         commitQuery.setIsExecutionClone(true);
         commitQuery.setObjectChangeSet(changeSetToWrite);
         commitQuery.setObject(objectToWrite);
         commitQuery.cascadeOnlyDependentParts();
         commitQuery.setModifyRow(null);
         session.executeQuery(commitQuery);
       }
       uowChangeSet.putNewObjectInChangesList(changeSetToWrite, session);
     }
   }
 }
  /** 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);
    }
  }
 /**
  * Commit changed of the objects of the class type in the change set. This allows for the order of
  * the classes to be processed optimally.
  */
 protected void commitChangedObjectsForClassWithChangeSet(
     UnitOfWorkChangeSet uowChangeSet, Class theClass) {
   Map<ObjectChangeSet, ObjectChangeSet> objectChangesList =
       uowChangeSet.getObjectChanges().get(theClass);
   if (objectChangesList != null) { // may be no changes for that class type.		
     ClassDescriptor descriptor = null;
     AbstractSession session = getSession();
     Collection<ObjectChangeSet> changes = objectChangesList.values();
     if (((UnitOfWorkImpl) session).shouldOrderUpdates()) {
       changes = new ArrayList(objectChangesList.values());
       Collections.sort((List) changes);
     }
     for (ObjectChangeSet changeSetToWrite : changes) {
       Object objectToWrite = changeSetToWrite.getUnitOfWorkClone();
       if (descriptor == null) {
         descriptor = session.getDescriptor(objectToWrite);
       }
       if (!isProcessedCommit(objectToWrite)) {
         // Commit and resume on failure can cause a new change set to be in existing, so need to
         // check here.
         WriteObjectQuery commitQuery = null;
         if (changeSetToWrite.isNew()) {
           commitQuery = new InsertObjectQuery();
         } else {
           commitQuery = new UpdateObjectQuery();
         }
         commitQuery.setIsExecutionClone(true);
         commitQuery.setDescriptor(descriptor);
         commitQuery.setObjectChangeSet(changeSetToWrite);
         commitQuery.setObject(objectToWrite);
         commitQuery.cascadeOnlyDependentParts();
         // removed checking session type to set cascade level
         // will always be a unitOfWork so we need to cascade dependent parts
         session.executeQuery(commitQuery);
       }
     }
   }
 }
  /**
   * Commit all of the objects as a single transaction. This should commit the object in the correct
   * order to maintain referential integrity.
   */
  public void commitAllObjectsWithChangeSet(UnitOfWorkChangeSet uowChangeSet)
      throws RuntimeException, DatabaseException, OptimisticLockException {
    reinitialize();
    this.isActive = true;
    this.session.beginTransaction();
    try {
      // PERF: if the number of classes in the project is large this loop can be a perf issue.
      // If only one class types changed, then avoid loop.
      if ((uowChangeSet.getObjectChanges().size() + uowChangeSet.getNewObjectChangeSets().size())
          <= 1) {
        Iterator<Class> classes = uowChangeSet.getNewObjectChangeSets().keySet().iterator();
        if (classes.hasNext()) {
          Class theClass = classes.next();
          commitNewObjectsForClassWithChangeSet(uowChangeSet, theClass);
        }
        classes = uowChangeSet.getObjectChanges().keySet().iterator();
        if (classes.hasNext()) {
          Class theClass = classes.next();
          commitChangedObjectsForClassWithChangeSet(uowChangeSet, theClass);
        }
      } else {
        // The commit order is all of the classes ordered by dependencies, this is done for deadlock
        // avoidance.
        List commitOrder = getCommitOrder();
        int size = commitOrder.size();
        for (int index = 0; index < size; index++) {
          Class theClass = (Class) commitOrder.get(index);
          commitAllObjectsForClassWithChangeSet(uowChangeSet, theClass);
        }
      }

      if (hasDeferredCalls()) {
        // Perform all batched up calls, done to avoid dependencies.
        for (List<Object[]> calls : this.deferredCalls.values()) {
          for (Object[] argument : calls) {
            ((DatabaseQueryMechanism) argument[1])
                .executeDeferredCall((DatasourceCall) argument[0]);
          }
        }
      }

      if (hasDataModifications()) {
        // Perform all batched up data modifications, done to avoid dependencies.
        for (Map.Entry<DatabaseMapping, List<Object[]>> entry : this.dataModifications.entrySet()) {
          List<Object[]> events = entry.getValue();
          int size = events.size();
          DatabaseMapping mapping = entry.getKey();
          for (int index = 0; index < size; index++) {
            Object[] event = events.get(index);
            mapping.performDataModificationEvent(event, getSession());
          }
        }
      }

      if (hasObjectsToDelete()) {
        // These are orphaned objects, to be deleted from private ownership updates.
        // TODO: These should be added to the unit of work deleted so they are deleted in the
        // correct order.
        List objects = getObjectsToDelete();
        int size = objects.size();
        reinitialize();
        for (int index = 0; index < size; index++) {
          this.session.deleteObject(objects.get(index));
        }
      }

      this.session.commitTransaction();
    } catch (RuntimeException exception) {
      this.session.rollbackTransaction();
      throw exception;
    } finally {
      reinitialize();
      this.isActive = false;
    }
  }