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

UnitOfWorkChangeSet

public class UnitOfWorkChangeSet extends Object implements Serializable, oracle.toplink.essentials.changesets.UnitOfWorkChangeSet

Purpose: This is the overall collection of changes.

Description: It holds all of the object changes and all ObjectChanges, with the same classType and primary keys, referenced in a changeSet should be the same object.

Fields Summary
protected transient Hashtable
objectChanges
This is the collection of ObjectChanges held by this ChangeSet
protected transient Hashtable
newObjectChangeSets
protected transient oracle.toplink.essentials.internal.helper.IdentityHashtable
cloneToObjectChangeSet
protected transient oracle.toplink.essentials.internal.helper.IdentityHashtable
objectChangeSetToUOWClone
protected oracle.toplink.essentials.internal.helper.IdentityHashtable
aggregateList
protected oracle.toplink.essentials.internal.helper.IdentityHashtable
allChangeSets
protected oracle.toplink.essentials.internal.helper.IdentityHashtable
deletedObjects
protected boolean
hasChanges
This attribute is set to true if a changeSet with changes has been added
protected boolean
hasForcedChanges
private transient Vector
sdkAllChangeSets
private transient int
objectChangeSetCounter
Constructors Summary
public UnitOfWorkChangeSet()
INTERNAL: Create a ChangeSet


             
      
        super();
        this.setHasChanges(false);
    
public UnitOfWorkChangeSet(byte[] bytes)
INTERNAL: Recreate a UnitOfWorkChangeSet that has been converted to a byte array with the getByteArrayRepresentation() method.

        java.io.ByteArrayInputStream byteIn = new java.io.ByteArrayInputStream(bytes);
        ObjectInputStream objectIn = new ObjectInputStream(byteIn);
		//bug 4416412: allChangeSets set directly instead of using setInternalAllChangeSets
        allChangeSets = (IdentityHashtable)objectIn.readObject();
        deletedObjects = (IdentityHashtable)objectIn.readObject();
    
Methods Summary
public voidaddDeletedObject(java.lang.Object object, AbstractSession session)
INTERNAL: Add the Deleted object to the changeSet

param
objectChanges prototype.changeset.ObjectChanges

        //CR 4080 - must prevent aggregate objects added to DeletedObjects list
        ClassDescriptor descriptor = session.getDescriptor(object);
        if (!descriptor.isAggregateCollectionDescriptor()) {
            ObjectChangeSet set = descriptor.getObjectBuilder().createObjectChangeSet(object, this, false, session);

            // needed for xml change set
            set.setShouldBeDeleted(true);
            getDeletedObjects().put(set, set);
        }
    
public voidaddDeletedObjects(oracle.toplink.essentials.internal.helper.IdentityHashtable deletedObjects, AbstractSession session)
INTERNAL: Add the Deleted objects to the changeSet

param
objectChanges prototype.changeset.ObjectChanges

        Enumeration enumtr = deletedObjects.keys();
        while (enumtr.hasMoreElements()) {
            Object object = enumtr.nextElement();

            this.addDeletedObject(object, session);
        }
    
public voidaddNewObjectChangeSet(ObjectChangeSet objectChanges, AbstractSession session)
INTERNAL: Add to the changes for 'object' object to this changeSet. This method will not add to the lists that are used for identity lookups. It is called specifically for new objects, and new object will be moved to the standard changes list by the QueryMechanism after insert.

see
addObjectChangeSetForIdentity()
param
objectChanges the new object change set

        if ((objectChanges == null)) {
            return;
        }
        IdentityHashtable changeSetTable = (IdentityHashtable)getNewObjectChangeSets().get(objectChanges.getClassType(session));
        if (changeSetTable == null) {
            // 2612538 - the default size of IdentityHashtable (32) is appropriate
            changeSetTable = new IdentityHashtable();
            getNewObjectChangeSets().put(objectChanges.getClassType(session), changeSetTable);
        }
        changeSetTable.put(objectChanges, objectChanges);
    
public voidaddObjectChangeSet(ObjectChangeSet objectChanges)
INTERNAL: Add to the changes for 'object' object to this changeSet. This method will not add to the lists that are used for identity lookups. The passed change set *must* either have changes or forced changes.

see
addObjectChangeSetForIdentity()
param
objectChanges prototype.changeset.ObjectChanges
param
object java.lang.Object

        if ((objectChanges == null)) {
            return;
        }

        // If this object change set has changes or forced changes then record this.  Must
        // be done for each change set added because some may not contain 'real' changes.  This
        // is the case for opt. read lock and forceUdpate.  Keep the flags separate because
        // we don't want to cache sync. a change set with no 'real' changes.
    	boolean objectChangeSetHasChanges = objectChanges.hasChanges();
        if (objectChangeSetHasChanges) {
            this.setHasChanges(true);
            this.hasForcedChanges = this.hasForcedChanges || objectChanges.hasForcedChanges();
        } else {
            // object change set doesn't have changes so it has to have forced changes.
            this.hasForcedChanges = true;
        }

        if (!objectChanges.isAggregate()) {
            if (objectChangeSetHasChanges) {
                // Each time I create a changeSet it is added to this list and when I compute a changeSet for this
                // object I again add it to these lists so that before this UOWChangeSet is
                // Serialised there is a copy of every changeSet which has changes affecting cache
                // in allChangeSets
                getAllChangeSets().put(objectChanges, objectChanges);
            }
            
            if (objectChanges.getCacheKey() != null) {
                Hashtable table = (Hashtable)getObjectChanges().get(objectChanges.getClassName());

                if (table == null) {
                    table = new Hashtable(2);
                    getObjectChanges().put(objectChanges.getClassName(), table);
                    table.put(objectChanges, objectChanges);
                } else {
                    table.put(objectChanges, objectChanges);
                }
            }
        }
    
public voidaddObjectChangeSetForIdentity(ObjectChangeSet objectChanges, java.lang.Object object)
INTERNAL: Add change records to the lists used to maintain identity. This will not actually add the changes to 'object' to the change set.

see
addObjectChangeSet()
param
objectChanges prototype.changeset.ObjectChanges

        if ((objectChanges == null) || (object == null)) {
            return;
        }

        if (objectChanges.isAggregate()) {
            getAggregateList().put(objectChanges, objectChanges);
        }

        getObjectChangeSetToUOWClone().put(objectChanges, object);
        getCloneToObjectChangeSet().put(object, objectChanges);

    
public ObjectChangeSetfindObjectChangeSet(ObjectChangeSet changeSet, oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet mergeFromChangeSet)
INTERNAL: This method can be used find the equivalent changeset within this UnitOfWorkChangeSet Aggregates, and new objects without primaryKeys from serialized ChangeSets will not be found Which may result in duplicates, in the UnitOfWorkChangeSet.

        Hashtable changes = (Hashtable)getObjectChanges().get(changeSet.getClassName());
        ObjectChangeSet potential = null;
        if (changes != null) {
            potential = (ObjectChangeSet)changes.get(changeSet);
        }
        if (potential == null) {
            potential = (ObjectChangeSet)this.getObjectChangeSetForClone(changeSet.getUnitOfWorkClone());
        }
        return potential;
    
public ObjectChangeSetfindOrIntegrateObjectChangeSet(ObjectChangeSet tofind, oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet mergeFromChangeSet)
INTERNAL: This method will be used during the merge process to either find an equivalent change set within this UnitOfWorkChangeSet or integrate that changeset into this UOW ChangeSet

        if (tofind == null) {
            return tofind;
        }
        ObjectChangeSet localChangeSet = this.findObjectChangeSet(tofind, mergeFromChangeSet);
        if (localChangeSet == null) {//not found locally then replace it with the one from the merging changeset
            localChangeSet = new ObjectChangeSet(tofind.getPrimaryKeys(), tofind.getClassType(), tofind.getUnitOfWorkClone(), this, tofind.isNew());
            this.addObjectChangeSetForIdentity(localChangeSet, localChangeSet.getUnitOfWorkClone());
        }
        return localChangeSet;
    
protected oracle.toplink.essentials.internal.helper.IdentityHashtablegetAggregateList()
INTERNAL: Get the Aggregate list. Lazy initialises the hashtable if required

return
oracle.toplink.essentials.internal.helper.IdentityHashtable

        if (aggregateList == null) {
            aggregateList = new IdentityHashtable();
        }
        return aggregateList;
    
public oracle.toplink.essentials.internal.helper.IdentityHashtablegetAllChangeSets()
INTERNAL: This method returns a reference to the collection

return
oracle.toplink.essentials.internal.helper.IdentityHashtable

        if (this.allChangeSets == null) {
            // 2612538 - the default size of IdentityHashtable (32) is appropriate
            this.allChangeSets = new IdentityHashtable();
        }
        return allChangeSets;
    
public oracle.toplink.essentials.internal.helper.IdentityHashtablegetCloneToObjectChangeSet()
INTERNAL: Get the clone to object change hash table. Lazy initialises the hashtable if required

return
oracle.toplink.essentials.internal.helper.IdentityHashtable

        if (cloneToObjectChangeSet == null) {
            cloneToObjectChangeSet = new IdentityHashtable();
        }
        return cloneToObjectChangeSet;
    
public oracle.toplink.essentials.internal.helper.IdentityHashtablegetDeletedObjects()
INTERNAL: This method returns the reference to the deleted objects from the changeSet

return
oracle.toplink.essentials.internal.helper.IdentityHashtable

        if (this.deletedObjects == null) {
            // 2612538 - the default size of IdentityHashtable (32) is appropriate
            this.deletedObjects = new IdentityHashtable();
        }
        return deletedObjects;
    
public java.util.HashtablegetNewObjectChangeSets()
INTERNAL: This method will return a reference to the new object change set collections

        if (this.newObjectChangeSets == null) {
            this.newObjectChangeSets = new java.util.Hashtable();
        }
        return this.newObjectChangeSets;
    
public oracle.toplink.essentials.changesets.ObjectChangeSetgetObjectChangeSetForClone(java.lang.Object clone)
ADVANCED: Get ChangeSet for a particular clone

return
ObjectChangeSet the changeSet that represents a particular clone

        if ((clone == null) || (getCloneToObjectChangeSet() == null)) {
            return null;
        }
        return (oracle.toplink.essentials.changesets.ObjectChangeSet)getCloneToObjectChangeSet().get(clone);
    
protected oracle.toplink.essentials.internal.helper.IdentityHashtablegetObjectChangeSetToUOWClone()
INTERNAL: This method returns a reference to the collection

return
oracle.toplink.essentials.internal.helper.IdentityHashtable

        if (this.objectChangeSetToUOWClone == null) {
            // 2612538 - the default size of IdentityHashtable (32) is appropriate
            this.objectChangeSetToUOWClone = new IdentityHashtable();
        }
        return objectChangeSetToUOWClone;
    
public java.util.HashtablegetObjectChanges()
INTERNAL: Returns the ObjectChanges held by this ChangeSet.

return
prototype.changeset.ObjectChanges

        if (objectChanges == null) {
            objectChanges = new Hashtable(2);
        }
        return objectChanges;
    
public java.lang.ObjectgetUOWCloneForObjectChangeSet(oracle.toplink.essentials.changesets.ObjectChangeSet changeSet)
ADVANCED: This method returns the Clone for a particular changeSet

return
Object the clone represented by the changeSet

        if ((changeSet == null) || (getObjectChangeSetToUOWClone() == null)) {
            return null;
        }
        return getObjectChangeSetToUOWClone().get(changeSet);
    
public booleanhasChanges()
INTERNAL: Returns true if the Unit Of Work change Set has changes

        // All of the object change sets were empty (none contained changes)
        // The this.hasChanges variable is set in addObjectChangeSet
        return (this.hasChanges || (!getDeletedObjects().isEmpty()));
    
public booleanhasForcedChanges()
INTERNAL: Returns true if this uowChangeSet contains an objectChangeSet that has forced SQL changes. This is true whenever CMPPolicy.getForceUpdate() == true.

return
boolean

        return this.hasForcedChanges;
    
public ObjectChangeSetmergeObjectChanges(ObjectChangeSet objectChangeSet, oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet mergeFromChangeSet)
INTERNAL: This method will be used to merge a change set into an UnitOfWorkChangeSet This method returns the local instance of the changeset

        ObjectChangeSet localChangeSet = this.findOrIntegrateObjectChangeSet(objectChangeSet, mergeFromChangeSet);
        if (localChangeSet != null) {
            localChangeSet.mergeObjectChanges(objectChangeSet, this, mergeFromChangeSet);
        }
        return localChangeSet;
    
public voidmergeUnitOfWorkChangeSet(oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet mergeFromChangeSet, AbstractSession session, boolean postCommit)
INTERNAL: THis method will be used to merge another changeset into this changeset. The Main use of this method is for non-deferred writes and checkpointing so that the acumulated changes are collected and merged at the end of the transaction

        Iterator iterator = mergeFromChangeSet.getObjectChanges().values().iterator();
        while (iterator.hasNext()) {
            //iterate over the classes
            Hashtable table = (Hashtable)iterator.next();
            Iterator changes = table.values().iterator();
            while (changes.hasNext()) {
                ObjectChangeSet objectChangeSet = (ObjectChangeSet)changes.next();
                objectChangeSet = mergeObjectChanges(objectChangeSet, mergeFromChangeSet);
                if (objectChangeSet.isNew() && !postCommit) {// if it is post commit then we can trust the cache key
                    this.addNewObjectChangeSet(objectChangeSet, session);
                } else {
                    this.addObjectChangeSet(objectChangeSet);
                }
            }
        }

        //merging a serialized UnitOfWorkChangeSet can result in duplicate deletes
        //if a delete for the same object already exists in this UOWChangeSet.
        Enumeration deletedEnum = mergeFromChangeSet.getDeletedObjects().elements();
        while (deletedEnum.hasMoreElements()) {
            ObjectChangeSet objectChangeSet = (ObjectChangeSet)deletedEnum.nextElement();
            ObjectChangeSet localObjectChangeSet = findObjectChangeSet(objectChangeSet, mergeFromChangeSet);
            if (localObjectChangeSet == null) {
                localObjectChangeSet = objectChangeSet;
            }
            this.getDeletedObjects().put(localObjectChangeSet, localObjectChangeSet);
        }
    
public voidputNewObjectInChangesList(ObjectChangeSet objectChangeSet, AbstractSession session)
INTERNAL: Used to rehash the new objects back into the objectChanges list for serialization

        this.addObjectChangeSet(objectChangeSet);
        removeObjectChangeSetFromNewList(objectChangeSet, session);
    
public voidremoveObjectChangeSet(ObjectChangeSet objectChanges)
INTERNAL: Add the changed Object's records to the ChangeSet

param
objectChanges prototype.changeset.ObjectChanges

        if (objectChanges == null) {
            return;
        }
        Object object = getObjectChangeSetToUOWClone().get(objectChanges);
        if (objectChanges.isAggregate()) {
            getAggregateList().remove(objectChanges);
        } else {
            // Bug 3294426 - index object changes by classname instead of class for remote classloader issues
            Hashtable table = (Hashtable)getObjectChanges().get(object.getClass().getName());
            if (table != null) {
                table.remove(objectChanges);
            }
        }
        getObjectChangeSetToUOWClone().remove(objectChanges);
        if (object != null) {
            getCloneToObjectChangeSet().remove(object);
        }
        getAllChangeSets().remove(objectChanges);
    
public voidremoveObjectChangeSetFromNewList(ObjectChangeSet objectChangeSet, AbstractSession session)
INTERNAL: Used to remove a new object from the new objects list once it has been inserted and added to the objectChangesList

        IdentityHashtable table = (IdentityHashtable)getNewObjectChangeSets().get(objectChangeSet.getClassType(session));
        if (table != null) {
            table.remove(objectChangeSet);
        }
    
protected voidsetCloneToObjectChangeSet(oracle.toplink.essentials.internal.helper.IdentityHashtable newCloneToObjectChangeSet)
INTERNAL: This method is used to set the hashtable for cloneToObject reference

param
newCloneToObjectChangeSet oracle.toplink.essentials.internal.helper.IdentityHashtable

        cloneToObjectChangeSet = newCloneToObjectChangeSet;
    
public voidsetHasChanges(boolean flag)
INTERNAL: Set whether the Unit Of Work change Set has changes

        this.hasChanges = flag;
    
public voidsetInternalAllChangeSets(java.util.Vector objectChangeSets)
INTERNAL: This method take a collection of ObjectChangeSet rebuilds this UOW change set to a ready to merge stage

        if (objectChangeSets == null) {
            return;
        }
        sdkAllChangeSets = objectChangeSets;

        for (int i = 0; i < objectChangeSets.size(); i++) {
            ObjectChangeSet objChangeSet = (ObjectChangeSet)objectChangeSets.elementAt(i);
            objChangeSet.setUOWChangeSet(this);

            if (objChangeSet.isAggregate()) {
                getAggregateList().put(objChangeSet, objChangeSet);

            } else if (objChangeSet.shouldBeDeleted()) {
                getDeletedObjects().put(objChangeSet, objChangeSet);
            } else {
                getAllChangeSets().put(objChangeSet, objChangeSet);
            }
            if (objChangeSet.getCacheKey() != null) {
                Hashtable table = (Hashtable)getObjectChanges().get(objChangeSet.getClassName());
                if (table == null) {
                    table = new Hashtable(2);
                    getObjectChanges().put(objChangeSet.getClassName(), table);
                }
                table.put(objChangeSet, objChangeSet);
            }
        }
    
protected voidsetObjectChangeSetToUOWClone(oracle.toplink.essentials.internal.helper.IdentityHashtable newObjectChangeSetToUOWClone)
INTERNAL: This method is used to insert a new collection into the UOWChangeSet.

param
newObjectChangeSetToUOWClone oracle.toplink.essentials.internal.helper.IdentityHashtable

        objectChangeSetToUOWClone = newObjectChangeSetToUOWClone;
    
protected voidsetObjectChanges(java.util.Hashtable objectChanges)
INTERNAL: Sets the collection of ObjectChanges in the change Set

param
newValue prototype.changeset.ObjectChanges

        this.objectChanges = objectChanges;