Program: 63912
Project: 63912
Buggy source:
/** 
 * INTERNAL: calculateChanges creates a change set for a particular object.  In DeferredChangeDetectionPolicy all mappings will be compared against a backup copy of the object.
 * @return an object change set describingthe changes to this object
 * @param clone the Object to compute a change set for
 * @param backUp the old version of the object to use for comparison
 * @param changeSet the change set to add changes to
 * @param session the current session
 * @param descriptor the descriptor for this object
 * @param shouldRaiseEvent indicates whether PreUpdate event should be risen (usually true)
 */
public ObjectChangeSet calculateChanges(Object clone,Object backUp,boolean isNew,UnitOfWorkChangeSet changeSet,UnitOfWorkImpl unitOfWork,ClassDescriptor descriptor,boolean shouldRaiseEvent){
  if (descriptor.getEventManager().hasAnyEventListeners() && shouldRaiseEvent) {
    WriteObjectQuery writeQuery=new WriteObjectQuery(clone.getClass());
    writeQuery.setObject(clone);
    writeQuery.setBackupClone(backUp);
    writeQuery.setSession(unitOfWork);
    writeQuery.setDescriptor(descriptor);
    descriptor.getEventManager().executeEvent(new DescriptorEvent(DescriptorEventManager.PreWriteEvent,writeQuery));
    if (isNew) {
      descriptor.getEventManager().executeEvent(new DescriptorEvent(DescriptorEventManager.PreInsertEvent,writeQuery));
    }
 else {
      descriptor.getEventManager().executeEvent(new DescriptorEvent(DescriptorEventManager.PreUpdateEvent,writeQuery));
    }
  }
  ObjectChangeSet changes=createObjectChangeSet(clone,backUp,changeSet,isNew,unitOfWork,descriptor);
  if (changes.hasChanges() && descriptor.hasMappingsPostCalculateChanges() && !changes.isNew()&& !unitOfWork.getCommitManager().isActive()&& !unitOfWork.isNestedUnitOfWork()) {
    int size=descriptor.getMappingsPostCalculateChanges().size();
    for (int i=0; i < size; i++) {
      DatabaseMapping mapping=descriptor.getMappingsPostCalculateChanges().get(i);
      org.eclipse.persistence.sessions.changesets.ChangeRecord record=changes.getChangesForAttributeNamed(mapping.getAttributeName());
      if (record != null) {
        mapping.postCalculateChanges(record,unitOfWork);
      }
    }
  }
  if (changes.getId() == null && !isNew && !changes.isAggregate()) {
    if (!(unitOfWork.isNestedUnitOfWork()) || (unitOfWork.isNestedUnitOfWork() && !(unitOfWork.isNewObjectInParent(clone) || unitOfWork.isUnregisteredNewObjectInParent(unitOfWork.getCloneToOriginals().get(clone))))) {
      Object id=descriptor.getObjectBuilder().extractPrimaryKeyFromObject(clone,unitOfWork,false);
      throw ValidationException.nullPrimaryKeyInUnitOfWorkClone(clone,id);
    }
  }
  if ((descriptor.getCMPPolicy() != null) && (descriptor.getCMPPolicy().getForceUpdate())) {
    changes.setHasCmpPolicyForcedUpdate(true);
  }
  if (!changes.hasForcedChangesFromCascadeLocking() && unitOfWork.hasOptimisticReadLockObjects()) {
    Boolean modifyVersionField=(Boolean)unitOfWork.getOptimisticReadLockObjects().get(clone);
    if (unitOfWork instanceof RepeatableWriteUnitOfWork && ((RepeatableWriteUnitOfWork)unitOfWork).getCumulativeUOWChangeSet() != null) {
      modifyVersionField=((RepeatableWriteUnitOfWork)unitOfWork).getCumulativeUOWChangeSet().getObjectChangeSetForClone(clone) == null;
    }
    changes.setShouldModifyVersionField(modifyVersionField);
  }
  if (changes.hasChanges() || changes.hasForcedChanges()) {
    return changes;
  }
  return null;
}

Fixed version (ground truth):
/** 
 * INTERNAL: calculateChanges creates a change set for a particular object.  In DeferredChangeDetectionPolicy all mappings will be compared against a backup copy of the object.
 * @return an object change set describingthe changes to this object
 * @param clone the Object to compute a change set for
 * @param backUp the old version of the object to use for comparison
 * @param changeSet the change set to add changes to
 * @param session the current session
 * @param descriptor the descriptor for this object
 * @param shouldRaiseEvent indicates whether PreUpdate event should be risen (usually true)
 */
public ObjectChangeSet calculateChanges(Object clone,Object backUp,boolean isNew,UnitOfWorkChangeSet changeSet,UnitOfWorkImpl unitOfWork,ClassDescriptor descriptor,boolean shouldRaiseEvent){
  if (descriptor.getEventManager().hasAnyEventListeners() && shouldRaiseEvent) {
    WriteObjectQuery writeQuery=new WriteObjectQuery(clone.getClass());
    writeQuery.setObject(clone);
    writeQuery.setBackupClone(backUp);
    writeQuery.setSession(unitOfWork);
    writeQuery.setDescriptor(descriptor);
    descriptor.getEventManager().executeEvent(new DescriptorEvent(DescriptorEventManager.PreWriteEvent,writeQuery));
    if (isNew) {
      descriptor.getEventManager().executeEvent(new DescriptorEvent(DescriptorEventManager.PreInsertEvent,writeQuery));
    }
 else {
      descriptor.getEventManager().executeEvent(new DescriptorEvent(DescriptorEventManager.PreUpdateEvent,writeQuery));
    }
  }
  ObjectChangeSet changes=createObjectChangeSet(clone,backUp,changeSet,isNew,unitOfWork,descriptor);
  if (changes.hasChanges() && descriptor.hasMappingsPostCalculateChanges() && !changes.isNew()&& !unitOfWork.getCommitManager().isActive()&& !unitOfWork.isNestedUnitOfWork()) {
    int size=descriptor.getMappingsPostCalculateChanges().size();
    for (int i=0; i < size; i++) {
      DatabaseMapping mapping=descriptor.getMappingsPostCalculateChanges().get(i);
      org.eclipse.persistence.sessions.changesets.ChangeRecord record=changes.getChangesForAttributeNamed(mapping.getAttributeName());
      if (record != null) {
        mapping.postCalculateChanges(record,unitOfWork);
      }
    }
  }
  if (changes.getId() == null && !isNew && !changes.isAggregate()) {
    if (!(unitOfWork.isNestedUnitOfWork()) || (unitOfWork.isNestedUnitOfWork() && !(unitOfWork.isNewObjectInParent(clone) || unitOfWork.isUnregisteredNewObjectInParent(unitOfWork.getCloneToOriginals().get(clone))))) {
      Object id=descriptor.getObjectBuilder().extractPrimaryKeyFromObject(clone,unitOfWork,false);
      throw ValidationException.nullPrimaryKeyInUnitOfWorkClone(clone,id);
    }
  }
  if ((descriptor.getCMPPolicy() != null) && (descriptor.getCMPPolicy().getForceUpdate())) {
    changes.setHasCmpPolicyForcedUpdate(true);
  }
  if (!changes.hasForcedChangesFromCascadeLocking() && unitOfWork.hasOptimisticReadLockObjects()) {
    Boolean modifyVersionField=(Boolean)unitOfWork.getOptimisticReadLockObjects().get(clone);
    if ((modifyVersionField != null) && (unitOfWork instanceof RepeatableWriteUnitOfWork) && (((RepeatableWriteUnitOfWork)unitOfWork).getCumulativeUOWChangeSet() != null)) {
      if (((RepeatableWriteUnitOfWork)unitOfWork).getCumulativeUOWChangeSet().getObjectChangeSetForClone(clone) == null) {
        modifyVersionField=Boolean.TRUE;
      }
    }
    changes.setShouldModifyVersionField(modifyVersionField);
  }
  if (changes.hasChanges() || changes.hasForcedChanges()) {
    return changes;
  }
  return null;
}