FileDocCategorySizeDatePackage
ObjectChangeSet.javaAPI DocGlassfish v2 API37498Tue May 22 16:54:44 BST 2007oracle.toplink.essentials.internal.sessions

ObjectChangeSet

public class ObjectChangeSet extends Object implements Serializable, ObjectChangeSet

Purpose: Hold the Records of change for a particular instance of an object.

Description: This class uses the Primary Keys of the Object it represents, and the class.

Fields Summary
protected Vector
changes
This is the collection of changes
protected Hashtable
attributesToChanges
protected boolean
shouldBeDeleted
protected CacheKey
cacheKey
protected transient Class
classType
protected String
className
protected boolean
isNew
protected boolean
isAggregate
protected Object
oldKey
protected Object
newKey
protected UnitOfWorkChangeSet
unitOfWorkChangeSet
This member variable holds the reference to the parent UnitOfWork Change Set
protected transient OptimisticLockingPolicy
optimisticLockingPolicy
Used in mergeObjectChanges method for writeLock and initialWriteLock comparison of the merged change sets
protected Object
initialWriteLockValue
protected Object
writeLockValue
protected boolean
isInvalid
Invalid change set shouldn't be merged into object in cache, rather the object should be invalidated
protected transient Object
cloneObject
protected boolean
hasVersionChange
protected Boolean
shouldModifyVersionField
protected boolean
hasCmpPolicyForcedUpdate
protected boolean
hasChangesFromCascadeLocking
protected transient HashSet
deferredSet
This is used during attribute level change tracking when a particular change was detected but that change can not be tracked (ie customer set entire collection in object).
Constructors Summary
public ObjectChangeSet()
The default constructor is used only by SDK XML project for mapping ObjectChangeSet

        super();
    
public ObjectChangeSet(Object cloneObject, UnitOfWorkChangeSet parent, boolean isNew)
This constructor is used to create an ObjectChangeSet that represents an aggregate object.

        this.cloneObject = cloneObject;
        this.shouldBeDeleted = false;
        this.classType = cloneObject.getClass();
        this.className = this.classType.getName();
        this.unitOfWorkChangeSet = parent;
        this.isNew = isNew;
    
public ObjectChangeSet(Vector primaryKey, Class classType, Object cloneObject, UnitOfWorkChangeSet parent, boolean isNew)
This constructor is used to create an ObjectChangeSet that represents a regular object.

        super();
        this.cloneObject = cloneObject;
        this.isNew = isNew;
        this.shouldBeDeleted = false;
        if ((primaryKey != null) && !oracle.toplink.essentials.internal.helper.Helper.containsNull(primaryKey, 0)) {
            this.cacheKey = new CacheKey(primaryKey);
        }
        this.classType = classType;
        this.className = this.classType.getName();
        this.unitOfWorkChangeSet = parent;
        this.isAggregate = false;
    
Methods Summary
public voidaddChange(oracle.toplink.essentials.internal.sessions.ChangeRecord changeRecord)

param
changeRecord prototype.changeset.ChangeRecord

        if (changeRecord == null) {
            return;
        }
        ChangeRecord existingChangeRecord = (ChangeRecord)getAttributesToChanges().get(changeRecord.getAttribute());
        // change tracking may add a change to an existing attribute fix that here.
        if ( existingChangeRecord != null){
            getChanges().remove(existingChangeRecord);
        }
        getChanges().addElement(changeRecord);
        getAttributesToChanges().put(changeRecord.getAttribute(), changeRecord);
        updateUOWChangeSet();
    
public voidclear()
INTERNAL: This method will clear the changerecords from a changeSet

        this.shouldBeDeleted = false;
        this.setOldKey(null);
        this.setNewKey(null);
        this.changes = null;
        this.attributesToChanges = null;
    
public booleancontainsChangesFromSynchronization()
INTERNAL: Convenience method used to query this change set after it has been sent by cache synchronization.

return
true if this change set should contain all change information, false if only the identity information should be available.

        return false;
    
public voiddeferredDetectionRequiredOn(java.lang.String attributeName)
INTERNAL: This method is used during attribute level change tracking when a particular change was detected but that change can not be tracked (ie customer set entire collection in object). In this case flag this attribute for deferred change detection at commit time.

        getDeferredSet().add(attributeName);
    
public booleanequals(java.lang.Object object)

return
boolean
param
objectChange prototype.changeset.ObjectChangeSet

        if (object instanceof ObjectChangeSet) {
            return equals((ObjectChangeSet)object);
        }
        return false;
    
public booleanequals(oracle.toplink.essentials.changesets.ObjectChangeSet objectChange)

return
boolean
param
objectChange prototype.changeset.ObjectChangeSet

        if (this == objectChange) {
            return true;
        } else if (getCacheKey() == null) {
            //new objects are compared based on identity
            return false;
        }

        return (getCacheKey().equals(((ObjectChangeSet)objectChange).getCacheKey()));
    
public java.util.HashtablegetAttributesToChanges()
INTERNAL: stores the change records indexed by the attribute names

        if (this.attributesToChanges == null) {
            this.attributesToChanges = new Hashtable(2);
        }
        return this.attributesToChanges;
    
public oracle.toplink.essentials.internal.identitymaps.CacheKeygetCacheKey()

return
java.util.Vector

        // this must not be lazy initialized as newness of the ObjectChangeSet and
        //equality are determined by the existence of a cachekey - GY
        return cacheKey;
    
public java.util.VectorgetChangedAttributeNames()
ADVANCED: This method will return a collection of the fieldnames of attributes changed in an object

        Vector names = new Vector();
        Enumeration attributes = getChanges().elements();
        while (attributes.hasMoreElements()) {
            names.addElement(((ChangeRecord)attributes.nextElement()).getAttribute());
        }
        return names;
    
public java.util.VectorgetChanges()
INTERNAL: This method returns a reference to the collection of changes within this changeSet

return
java.util.Vector

        if (this.changes == null) {
            this.changes = new Vector(1);
        }
        return changes;
    
public oracle.toplink.essentials.changesets.ChangeRecordgetChangesForAttributeNamed(java.lang.String attributeName)
INTERNAL: returns the change record for the specified attribute name

        return (ChangeRecord)this.getAttributesToChanges().get(attributeName);
    
public java.lang.StringgetClassName()
ADVANCE: This method returns the class type that this changeSet Represents. The class type should be used if the class is desired.

return
java.lang.Class

        return className;
    
public java.lang.ClassgetClassType()
INTERNAL: This method returns the class type that this changeSet represents. The class type must be initialized, before this method is called.

return
java.lang.Class or null if the class type isn't initialized.

        return classType;
    
public java.lang.ClassgetClassType(oracle.toplink.essentials.sessions.Session session)
ADVANCE: This method returns the class type that this changeSet Represents. This requires the session to reload the class on serialization.

return
java.lang.Class

        if (classType == null) {
            classType = (Class)((AbstractSession)session).getDatasourcePlatform().getConversionManager().convertObject(getClassName(), ClassConstants.CLASS);
        }
        return classType;
    
public java.util.HashSetgetDeferredSet()
This set contains the list of attributes that must be calculated at commit time.

        if (deferredSet == null){
            this.deferredSet = new HashSet();
        }
        return deferredSet;
    
public java.lang.ObjectgetInitialWriteLockValue()
INTERNAL: This method is used to return the initial lock value of the object this changeSet represents

return
java.lang.Object

        return initialWriteLockValue;
    
public java.lang.ObjectgetNewKey()
This method returns the key value that this object will be stored under in it's Respective hashmap.

        return this.newKey;
    
public java.lang.ObjectgetOldKey()
This method returns the key value that this object was stored under in it's Respective hashmap.

        return this.oldKey;
    
public java.util.VectorgetPrimaryKeys()
ADVANCED: This method returns the primary keys for the object that this change set represents

return
java.util.Vector

        if (getCacheKey() == null) {
            return null;
        }
        return getCacheKey().getKey();
    
public java.lang.ObjectgetTargetVersionOfSourceObject(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: This method is used to return the complex object specified within the change record. The object is collected from the session which, in this case, is the unit of work. The object's changed attributes will be merged and added to the identity map

param
session oracle.toplink.essentials.publicinterface.Session

        return getTargetVersionOfSourceObject(session, false);
    
public java.lang.ObjectgetTargetVersionOfSourceObject(oracle.toplink.essentials.internal.sessions.AbstractSession session, boolean shouldRead)
INTERNAL: This method is used to return the complex object specified within the change record. The object is collected from the session which, in this case, is the unit of work. The object's changed attributes will be merged and added to the identity map

param
shouldRead boolean if the object can not be found should it be read in from the database
param
session oracle.toplink.essentials.publicinterface.Session

        Object attributeValue = null;
        ClassDescriptor descriptor = session.getDescriptor(getClassType(session));

        if (session.isUnitOfWork()) {// The unit of works will have a copy or a new instance must be made
            if (((UnitOfWorkImpl)session).getLifecycle() == UnitOfWorkImpl.MergePending) {// we are merging the unit of work into the original
                attributeValue = ((UnitOfWorkImpl)session).getOriginalVersionOfObjectOrNull(((UnitOfWorkChangeSet)getUOWChangeSet()).getObjectChangeSetToUOWClone().get(this));
            } else {
                //we are merging something else within the unit of work.
                // this is most likely because we are updating a backup clone and can retrieve
                //the working clone as the result
                attributeValue = ((UnitOfWorkChangeSet)getUOWChangeSet()).getObjectChangeSetToUOWClone().get(this);
            }
        } else {//It is not a unitOfWork so we must be merging into a distributed cache
            attributeValue = session.getIdentityMapAccessorInstance().getIdentityMapManager().getFromIdentityMap(getPrimaryKeys(), getClassType(session), descriptor);

        }
        if ((attributeValue == null) && (shouldRead)) {
            // If the cache does not have a copy and I should read it from the database
            // Then load the object if possible
            ReadObjectQuery query = new ReadObjectQuery();
            query.setShouldUseWrapperPolicy(false);
            query.setReferenceClass(getClassType(session));
            query.setSelectionKey(getPrimaryKeys());
            attributeValue = session.executeQuery(query);
        }
        return attributeValue;
    
public oracle.toplink.essentials.changesets.UnitOfWorkChangeSetgetUOWChangeSet()
ADVANCED: This method is used to return the parent ChangeSet

return
prototype.changeset.UnitOfWorkChangeSet

        return unitOfWorkChangeSet;
    
public java.lang.ObjectgetUnitOfWorkClone()
INTERNAL: Returns the UnitOfWork Clone that this ChangeSet was built For

        return this.cloneObject;
    
public java.lang.ObjectgetWriteLockValue()
INTERNAL: This method is used to return the lock value of the object this changeSet represents

return
java.lang.Object

        return writeLockValue;
    
public booleanhasChangeFor(java.lang.String attributeName)
ADVANCED: This method will return true if the specified attributue has been changed

param
String the name of the attribute to search for

        Enumeration attributes = getChanges().elements();
        while (attributes.hasMoreElements()) {
            if (((ChangeRecord)attributes.nextElement()).getAttribute().equals(attributeName)) {
                return true;
            }
        }
        return false;
    
public booleanhasChanges()
ADVANCED: Returns true if this particular changeSet has changes.

return
boolean

        // a change set must also be considered dirty if only the version number has been updated
        // and the version is not a mapped field.  This is required to propagate the change
        // set via cache sync. to avoid opt. lock exceptions on the remote servers.
        return this.hasVersionChange || !this.getChanges().isEmpty();
    
public booleanhasCmpPolicyForcedUpdate()
INTERNAL:

        return this.hasCmpPolicyForcedUpdate;
    
public booleanhasDeferredAttributes()
Check to see if there are any attributes that must be calculated at commit time.

        return ! (deferredSet == null  || this.deferredSet.isEmpty());
    
public booleanhasForcedChanges()
INTERNAL: Returns true if this particular changeSet has forced SQL changes. This is true whenever CMPPolicy.getForceUpdate() == true or if the object has been marked for opt. read lock (uow.forceUpdateToVersionField). Kept separate from 'hasChanges' because we don't want to merge or cache sync. a change set that has no 'real' changes.

return
boolean

        return this.shouldModifyVersionField != null || this.hasCmpPolicyForcedUpdate;
    
public booleanhasForcedChangesFromCascadeLocking()
INTERNAL: Returns true if this particular changeSet has forced SQL changes because of a cascade optimistic locking policy.

return
boolean

        return this.hasChangesFromCascadeLocking;
    
public booleanhasKeys()
INTERNAL: Returns true if this particular changeSet has a Key.

return
boolean

        return (this.newKey != null) || (this.oldKey != null);
    
public inthashCode()
This method overrides the hashcode method. If this set has a cacheKey then return the hashcode of the cache key, otherwise return the identity hashcode of this object.

return
int

        if (getCacheKey() == null) {
            //new objects are compared based on identity
            return System.identityHashCode(this);
        }
        return getCacheKey().hashCode();
    
public booleanisAggregate()
INTERNAL: Used to determine if the object change set represents an aggregate object

return
boolean

        return isAggregate;
    
public booleanisInvalid()
INTERNAL: Indicates whether the change set is invalid.

return
boolean

        return isInvalid;
    
public booleanisNew()
ADVANCED: Returns true if this ObjectChangeSet represents a new object

return
boolean

        return isNew;
    
public voidmergeObjectChanges(oracle.toplink.essentials.internal.sessions.ObjectChangeSet changeSetToMergeFrom, oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet mergeToChangeSet, oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet mergeFromChangeSet)
INTERNAL: This method will be used to merge changes from a supplied ObjectChangeSet into this changeSet.

        if (this == changeSetToMergeFrom || this.isInvalid()) {
            return;
        }
        if(changeSetToMergeFrom.optimisticLockingPolicy != null) {
            // optimisticLockingPolicy != null guarantees initialWriteLockValue != null
            if(this.optimisticLockingPolicy == null) {
                this.optimisticLockingPolicy = changeSetToMergeFrom.optimisticLockingPolicy;
                this.initialWriteLockValue = changeSetToMergeFrom.initialWriteLockValue;
                this.writeLockValue = changeSetToMergeFrom.writeLockValue;
            } else {
                // optimisticLockingPolicy != null guarantees initialWriteLockValue != null
                Object writeLockValueToCompare = this.writeLockValue;
                if(writeLockValueToCompare == null) {
                    writeLockValueToCompare = this.initialWriteLockValue;
                }
                // In this merge initialWriteLockValue of this changeSet differes from 
                // writeLockValue of the changeSetToMergeFrom into which the merge was performed.
                // Example:
                // Original registered with version 1, the clone changed to version 2, uow.writeChanges is called:
                // the corresponding "this" changeSet has initialWriteLockValue = 1 and writeLockValue = 2;
                // custom update performed next changing the version of the object in the db to 3;
                // the clone is refreshed in the uow - not it's version is 3;
                // the cloned is changed to version 4, uow.commit is called:
                // the corresponding changeSetToMergeFrom has initialWriteLockValue = 3 and writeLockValue = 4.
                // This change set should be invalidated - the custom update would not be reflected after merge,
                // therefore nor merge into cache should be performed but rather the object in the cache should be invalidated.
                if(this.optimisticLockingPolicy.compareWriteLockValues(writeLockValueToCompare, changeSetToMergeFrom.initialWriteLockValue) != 0) {
                    this.isInvalid = true;
                    return;
                }
                this.writeLockValue = changeSetToMergeFrom.writeLockValue;
            }
        }
        for (int index = 0; index < changeSetToMergeFrom.getChanges().size(); ++index) {
            ChangeRecord record = (ChangeRecord)changeSetToMergeFrom.getChanges().get(index);
            ChangeRecord thisRecord = (ChangeRecord) this.getChangesForAttributeNamed(record.getAttribute());
            if (thisRecord == null) {
                record.updateReferences(mergeToChangeSet, mergeFromChangeSet);
                record.setOwner(this);
                this.addChange(record);
            } else {
                thisRecord.mergeRecord(record, mergeToChangeSet, mergeFromChangeSet);
            }
        }
        this.shouldBeDeleted = changeSetToMergeFrom.shouldBeDeleted;
        this.setOldKey(changeSetToMergeFrom.oldKey);
        this.setNewKey(changeSetToMergeFrom.newKey);
        this.hasVersionChange = changeSetToMergeFrom.hasVersionChange;
        this.shouldModifyVersionField = changeSetToMergeFrom.shouldModifyVersionField;
        this.hasCmpPolicyForcedUpdate = changeSetToMergeFrom.hasCmpPolicyForcedUpdate;
        this.hasChangesFromCascadeLocking = changeSetToMergeFrom.hasChangesFromCascadeLocking;
    
public voidprepareChangeRecordsForSynchronization(oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Iterate through the change records and ensure the cache synchronization types are set on the change sets associated with those records.

        Enumeration records = getChanges().elements();
        while (records.hasMoreElements()) {
            ((ChangeRecord)records.nextElement()).prepareForSynchronization(session);
        }
    
public voidreadCompleteChangeSet(java.io.ObjectInputStream stream)
INTERNAL: Helper method used by readObject to read a completely serialized change set from the stream

        readIdentityInformation(stream);
        // bug 3526981 - avoid side effects of setter methods by directly assigning variables
        // still calling setOldKey to avoid duplicating the code in that method
        changes = (Vector)stream.readObject();
        setOldKey(stream.readObject());
        newKey = stream.readObject();
    
public voidreadIdentityInformation(java.io.ObjectInputStream stream)
INTERNAL: Helper method used by readObject to read just the information about object identity from a serialized stream.

        // bug 3526981 - avoid side effects of setter methods by directly assigning variables
        cacheKey = (CacheKey)stream.readObject();
        className = (String)stream.readObject();
        writeLockValue = stream.readObject();
    
public voidremoveChange(java.lang.String attributeName)
INTERNAL: Remove change. Used by the event mechanism to reset changes after client has updated the object within an event;

        Object record = getChangesForAttributeNamed(attributeName);
        if (record != null){
            getChanges().removeElement(record);
        }
    
protected voidremoveFromIdentityMap(oracle.toplink.essentials.internal.sessions.AbstractSession session)
Remove object represent this change set from identity map. If change set is in XML format, rebuild pk to the correct class type from String

        session.getIdentityMapAccessor().removeFromIdentityMap(getPrimaryKeys(), getClassType(session));
    
public voidsetCacheKey(oracle.toplink.essentials.internal.identitymaps.CacheKey cacheKey)

return
java.util.Vector

        this.cacheKey = cacheKey;
    
public voidsetChanges(java.util.Vector changesList)

param
newValue java.util.Vector

        this.changes = changesList;
        updateUOWChangeSet();
    
public voidsetClassName(java.lang.String newValue)
INTERNAL:

param
newValue java.lang.String

        this.className = newValue;
    
public voidsetClassType(java.lang.Class newValue)

param
newValue java.lang.Class

        this.classType = newValue;
    
public voidsetHasCmpPolicyForcedUpdate(boolean hasCmpPolicyForcedUpdate)
INTERNAL:

        this.hasCmpPolicyForcedUpdate = hasCmpPolicyForcedUpdate;
    
public voidsetHasForcedChangesFromCascadeLocking(boolean newValue)
INTERNAL: * Used by calculateChanges to mark this ObjectChangeSet as having to be flushed to the db steming from a cascade optimistic locking policy.

        this.setShouldModifyVersionField(Boolean.TRUE);
        this.hasChangesFromCascadeLocking = newValue;
    
public voidsetInitialWriteLockValue(java.lang.Object initialWriteLockValue)
ADVANCED: This method is used to set the initial writeLock value for an ObjectChangeSet. The initial value will only be set once, and can not be overwritten.

param
initialWriteLockValue java.lang.Object

        if (this.initialWriteLockValue == null) {
            this.initialWriteLockValue = initialWriteLockValue;
        }
    
public voidsetIsAggregate(boolean isAggregate)
INTERNAL: Set if this object change Set represents an aggregate

param
isAggregate boolean true if the ChangeSet represents an aggregate

        this.isAggregate = isAggregate;
    
protected voidsetIsNew(boolean newIsNew)
INTERNAL: Set whether this ObjectChanges represents a new Object

param
newIsNew boolean true if this ChangeSet represents a new object

        isNew = newIsNew;
    
public voidsetNewKey(java.lang.Object key)
This method is used to set the value that this object will be stored under in its respected map collection

        this.newKey = key;
    
public voidsetOldKey(java.lang.Object key)
This method is used to set the value that this object was stored under in its respected map collection

        //may be merging changeSets lets make sure that we can remove based on the
        //old key when we finally merge.
        if ((key == null) || (this.oldKey == null)) {
            this.oldKey = key;
        }
    
public voidsetOptimisticLockingPolicyAndInitialWriteLockValue(oracle.toplink.essentials.internal.descriptors.OptimisticLockingPolicy optimisticLockingPolicy, oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: This method should ONLY be used to set the initial writeLock value for an ObjectChangeSet when it is first built.

param
newWriteLockValue java.lang.Object

        this.optimisticLockingPolicy = optimisticLockingPolicy;
        this.initialWriteLockValue = optimisticLockingPolicy.getWriteLockValue(cloneObject, getPrimaryKeys(), session);
    
public voidsetPrimaryKeys(java.util.Vector key)
INTERNAL:

        if (key == null) {
            return;
        }
        if (getCacheKey() == null) {
            setCacheKey(new CacheKey(key));
        } else {
            getCacheKey().setKey(key);
        }
    
public voidsetShouldBeDeleted(boolean newValue)
This method was created in VisualAge.

param
newValue boolean

        this.shouldBeDeleted = newValue;
    
public voidsetShouldModifyVersionField(java.lang.Boolean shouldModifyVersionField)
INTERNAL: Holds a Boolean indicating whether version field should be modified. This Boolean is set by forcedUpdate into uow.getOptimisticReadLockObjects() for the clone object and copied here (so don't need to search for it again in uow.getOptimisticReadLockObjects()).

        this.shouldModifyVersionField = shouldModifyVersionField;
        if(shouldModifyVersionField != null && shouldModifyVersionField.booleanValue()) {
            // mark the version number as 'dirty'
            // Note that at this point there is no newWriteLockValue - it will be set later.
            // This flag is set to indicate that the change set WILL have changes.
            this.hasVersionChange = true;
        }
    
public voidsetUOWChangeSet(oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet newUnitOfWorkChangeSet)
INTERNAL: Used to set the parent change Set

param
newUnitOfWorkChangeSet prototype.changeset.UnitOfWorkChangeSet

        unitOfWorkChangeSet = newUnitOfWorkChangeSet;
    
public voidsetWriteLockValue(java.lang.Object newWriteLockValue)
ADVANCED: This method is used to set the writeLock value for an ObjectChangeSet Any changes to the write lock value should to through setWriteLockValue(Object obj) so that th change set is marked as being dirty.

param
newWriteLockValue java.lang.Object

        this.writeLockValue = newWriteLockValue;

        // mark the version number as 'dirty'
        this.hasVersionChange = true;
        updateUOWChangeSet();
    
public booleanshouldBeDeleted()
This method was created in VisualAge.

return
boolean

        return shouldBeDeleted;
    
public booleanshouldInvalidateObject(java.lang.Object original, oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: Indicates whether the object in session cache should be invalidated.

param
original Object is from session's cache into which the changes are about to be merged, non null.
param
session AbstractSession into which the changes are about to be merged;

        // Either no optimistic locking or no version change.
        if (optimisticLockingPolicy == null) {
            return false;
        }
        
        if(isInvalid()) {
            return true;
        }
        
        Object originalWriteLockValue = optimisticLockingPolicy.getWriteLockValue(original, getPrimaryKeys(), session);
        // initialWriteLockValue and originalWriteLockValue are not equal.
        // Example: 
        // original registered in uow with version 1 (originalWriteLockValue);
        // uow.beginEarlyTransaction();
        // custom update run through the uow changes the version on the object in the db to 2;
        // the clone is refreshed - now it has version 2;
        // on uow.commit or uow.writeChanges changeSet is created with initialWriteLockValue = 2;
        // The original in the cache should be invalidated - the custom update would not be reflected after merge.
        if (optimisticLockingPolicy.compareWriteLockValues(initialWriteLockValue, originalWriteLockValue) != 0) {
            return true;
        } else {
            return false;
        }
    
public java.lang.BooleanshouldModifyVersionField()
INTERNAL: Holds a Boolean indicating whether version field should be modified.

        return this.shouldModifyVersionField;
    
public java.lang.StringtoString()

        return this.getClass().getName() + "(" + this.getClassName() + ")" + getChanges().toString();
    
public voidupdateChangeRecordForAttribute(java.lang.String attributeName, java.lang.Object value)
INTERNAL: Used to update a changeRecord that is stored in the CHangeSet with a new value.

        ChangeRecord changeRecord = (ChangeRecord)getChangesForAttributeNamed(attributeName);
        if (changeRecord != null) {
            changeRecord.updateChangeRecordWithNewValue(value);
        }
    
public voidupdateChangeRecordForAttribute(oracle.toplink.essentials.mappings.DatabaseMapping mapping, java.lang.Object value)
INTERNAL: Used to update a changeRecord that is stored in the CHangeSet with a new value.

        String attributeName = mapping.getAttributeName();
        ChangeRecord changeRecord = (ChangeRecord)getChangesForAttributeNamed(attributeName);

        // bug 2641228 always ensure that we convert the value to the correct type
        value = ConversionManager.getDefaultManager().convertObject(value, mapping.getAttributeClassification());
        if (changeRecord != null) {
            changeRecord.updateChangeRecordWithNewValue(value);
        } else if (mapping.isDirectToFieldMapping()) {
            //if it is direct to field then this is most likely the result of a forced update and
            // we will need to merge this object
            changeRecord = new DirectToFieldChangeRecord(this);
            changeRecord.setAttribute(attributeName);
            changeRecord.setMapping(mapping);
            ((DirectToFieldChangeRecord)changeRecord).setNewValue(value);
            this.addChange(changeRecord);
        }
    
public voidupdateChangeRecordForAttributeWithMappedObject(java.lang.String attributeName, java.lang.Object value, oracle.toplink.essentials.internal.sessions.AbstractSession session)
ADVANCED: Used to update a changeRecord that is stored in the CHangeSet with a new value. Used when the new value is a mapped object.

        ObjectChangeSet referenceChangeSet = (ObjectChangeSet)this.getUOWChangeSet().getObjectChangeSetForClone(value);
        if (referenceChangeSet == null) {
            ClassDescriptor descriptor = session.getDescriptor(value.getClass());
            if (descriptor != null) {
                referenceChangeSet = descriptor.getObjectBuilder().createObjectChangeSet(value, (UnitOfWorkChangeSet)this.getUOWChangeSet(), false, session);
            }
        }
        updateChangeRecordForAttribute(attributeName, referenceChangeSet);
    
public voidupdateReferences(oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet localChangeSet, oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet mergingChangeSet)
INTERNAL: This method will be used when merging changesets into other changesets. It will fix references within a changeSet so that it's records point to changesets within this UOWChangeSet.

        for (int index = 0; index < this.getChanges().size(); ++index) {
            ChangeRecord record = (ChangeRecord)this.getChanges().get(index);
            record.updateReferences(localChangeSet, mergingChangeSet);
            record.setOwner(this);
        }
    
protected voidupdateUOWChangeSet()

        // needed to explicitly mark parent uow as having changes.  This is needed in the
        // case of Optimistic read locking and ForceUpdate.  In these scenarios, the object
        // change set can be modified to contain 'real' changes after the uow change set has
        // computed its 'hasChanges' flag.  If not done, the change set will not be merged.
        if (this.getUOWChangeSet() != null) {
            ((oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet)this.getUOWChangeSet()).setHasChanges(this.hasChanges());
        }
    
public voidwriteCompleteChangeSet(java.io.ObjectOutputStream stream)
INTERNAL: Helper method to readObject. Completely write this ObjectChangeSet to the stream

        writeIdentityInformation(stream);
        stream.writeObject(changes);
        stream.writeObject(oldKey);
        stream.writeObject(newKey);
    
public voidwriteIdentityInformation(java.io.ObjectOutputStream stream)
INTERNAL: Helper method to writeObject. Write only the information necessary to identify this ObjectChangeSet to the stream

        stream.writeObject(cacheKey);
        stream.writeObject(className);
        stream.writeObject(writeLockValue);