Module org.eclipse.persistence.core
Class MergeManager
- java.lang.Object
-
- org.eclipse.persistence.internal.sessions.MergeManager
-
public class MergeManager extends Object
Purpose: Used to manage the merge of two objects in a unit of work.
- Since:
- TOPLink/Java 1.1
- Author:
- James Sutherland
-
-
Field Summary
Fields Modifier and Type Field Description protected ArrayList<CacheKey>acquiredLocksUsed to store the list of locks that this merge manager has acquired for this mergestatic intCASCADE_ALL_PARTSstatic intCASCADE_BY_MAPPINGstatic intCASCADE_PRIVATE_PARTSprotected intcascadePolicyPolicy that determines how the merge will cascade to its object's parts.protected static intCHANGES_INTO_DISTRIBUTED_CACHEprotected static intCLONE_INTO_WORKING_COPYprotected static intCLONE_WITH_REFS_INTO_WORKING_COPYprotected booleanforceCascadeForce cascade merge even if a clone is already registeredprotected booleanisForRefreshrecords that this merge process is for a refreshprotected booleanisTransitionedToDeferredLocksrecords that deferred locks have been employed for the merge processstatic booleanLOCK_ON_MERGEBackdoor to disable merge locks.protected ThreadlockThreadsave the currentThread for later comparison to the activeThread in case they don't matchprotected IdentityHashMap<Object,Object>mergedNewObjectsUsed to keep track of merged new objects.protected intmergePolicyPolicy that determines merge type (i.e.static intNO_CASCADEprotected Map<Object,ObjectDescriptor>objectDescriptorsUsed only while refreshing objects on remote sessionprotected Map<AbstractSession,Map<Object,Object>>objectsAlreadyMergedUsed to unravel recursion.protected static intORIGINAL_INTO_WORKING_COPYprotected LinkedNodequeueNodeStores the node that holds this mergemanager within the WriteLocksManager queueprotected static intREFRESH_REMOTE_OBJECTprotected AbstractSessionsessionThe unit of work merging for.protected longsystemTimeStored so that all objects merged by a merge manager can have the same readTime.protected static intWORKING_COPY_INTO_ORIGINALprotected static intWORKING_COPY_INTO_REMOTEprotected ObjectwriteLockQueuedIf this variable is not null then the mergemanager is waiting on a particular primary key
-
Constructor Summary
Constructors Constructor Description MergeManager(AbstractSession session)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description voidcascadeAllParts()Cascade all parts, this is the default for the merge.voidcascadePrivateParts()Cascade private parts, this can be used to merge clone when using RMI.voidcheckNewObjectLockVersion(Object clone, Object primaryKey, ClassDescriptor descriptor, UnitOfWorkImpl unitOfWork)Check if the new object's version has been set, if so, then it was an existing object that was deleted.voiddontCascadeParts()Merge only direct parts, this can be used to merge clone when using RMI.ArrayList<CacheKey>getAcquiredLocks()intgetCascadePolicy()ThreadgetLockThread()INTERNAL:IdentityHashMap<Object,Object>getMergedNewObjects()INTERNAL: Used to return a map containing new objects found through the registerObjectForMergeCloneIntoWorkingCopy method.ObjectgetMergedObject(Object key, AbstractSession targetSession)protected intgetMergePolicy()Map<Object,ObjectDescriptor>getObjectDescriptors()Map<AbstractSession,Map<Object,Object>>getObjectsAlreadyMerged()ObjectgetObjectToMerge(Object sourceValue, ClassDescriptor descriptor, AbstractSession targetSession)LinkedNodegetQueueNode()INTENRAL: Used to get the node that this merge manager is stored in, within the WriteLocksManager write lockers queueAbstractSessiongetSession()longgetSystemTime()Get the stored value of the current time.ObjectgetTargetVersionOfSourceObject(Object source, ClassDescriptor descriptor, AbstractSession targetSession)Return the corresponding value that should be assigned to the target object for the source object.ObjectgetWriteLockQueued()INTENRAL: Used to get the object that the merge manager is waiting on, in order to acquire locksbooleanisAlreadyMerged(Object object, AbstractSession targetSession)booleanisForRefresh()booleanisTransitionedToDeferredLocks()INTERNAL: Will return if the merge process has transitioned the active merge locks to deferred locks for readlock deadlock avoidance.ObjectmergeChanges(Object object, ObjectChangeSet objectChangeSet, AbstractSession targetSession)Recursively merge changes in the object dependent on the merge policy.protected ObjectmergeChangesForRefreshingRemoteObject(Object serverSideDomainObject)Recursively merge the RMI clone from the server into the client unit of work working copy.voidmergeChangesFromChangeSet(UnitOfWorkChangeSet uowChangeSet)INTERNAL: Merge the changes to all objects to session's cache.protected ObjectmergeChangesIntoDistributedCache(Object original, ObjectChangeSet changeSet)Merge the changes specified within the changeSet into the cache.protected ObjectmergeChangesOfCloneIntoWorkingCopy(Object rmiClone)Recursively merge to rmi clone into the unit of work working copy.protected ObjectmergeChangesOfOriginalIntoWorkingCopy(Object clone)Recursively merge to original from its parent into the clone.protected ObjectmergeChangesOfWorkingCopyIntoOriginal(Object clone, ObjectChangeSet objectChangeSet)Recursively merge to clone into the original in its parent.protected CacheKeymergeChangesOfWorkingCopyIntoOriginal(Object clone, ObjectChangeSet objectChangeSet, ClassDescriptor descriptor, AbstractSession targetSession, UnitOfWorkImpl unitOfWork)Recursively merge to clone into the original in its parent.ObjectmergeChangesOfWorkingCopyIntoRemote(Object clone)Recursively merge changes in the object dependent on the merge policy.voidmergeCloneIntoWorkingCopy()This can be used by the user for merging clones from RMI into the unit of work.voidmergeCloneWithReferencesIntoWorkingCopy()This is used during the merge of dependent objects referencing independent objects, where you want the independent objects merged as well.voidmergeIntoDistributedCache()This is used during cache synchronization to merge the changes into the distributed cache.ObjectmergeNewObjectIntoCache(ObjectChangeSet changeSet)Merge a change set for a new object into the cache.voidmergeOriginalIntoWorkingCopy()This is used to revert changes to objects, or during refreshes.voidmergeWorkingCopyIntoOriginal()This is used during the unit of work commit to merge changes into the parent.voidmergeWorkingCopyIntoRemote()This is used during the unit of work commit to merge changes into the parent.voidrecordMerge(Object key, Object value, AbstractSession targetSession)voidrefreshRemoteObject()INTERNAL: This is used to refresh remote session objectObjectregisterExistingObjectOfReadOnlyClassInNestedTransaction(Object source, ClassDescriptor descriptor, AbstractSession targetSession)INTERNAL: Used to register an existing object used in nested unit of work with read-only class in root unit of work.protected ObjectregisterObjectForMergeCloneIntoWorkingCopy(Object clone, boolean shouldForceCascade)INTERNAL: When merging from a clone when the cache cannot be guaranteed the object must be first read if it is existing and not in the cache.voidregisterRemovedNewObjectIfRequired(Object removedObject)Determine if the object is a registered new object, and that this is a nested unit of work merge into the parent.voidsetCascadePolicy(int cascadePolicy)voidsetForceCascade(boolean forceCascade)voidsetForRefresh(boolean isforRefresh)voidsetLockThread(Thread lockThread)INTERNAL: Save the currentThread for later comparison to the activeThread in case they don't matchprotected voidsetMergePolicy(int mergePolicy)voidsetObjectDescriptors(Map<Object,ObjectDescriptor> objectDescriptors)protected voidsetObjectsAlreadyMerged(Map<AbstractSession,Map<Object,Object>> objectsAlreadyMerged)voidsetQueueNode(LinkedNode node)INTENRAL: Used to set the node that this merge manager is stored in, within the WriteLocksManager write lockers queueprotected voidsetSession(AbstractSession session)voidsetWriteLockQueued(Object primaryKey)INTENRAL: Used to set the object that the merge manager is waiting on, in order to acquire locks If this value is null then the merge manager is not waiting on any locks.booleanshouldCascadeAllParts()Flag used to determine if all parts should be cascadedbooleanshouldCascadeByMapping()Flag used to determine that the mappings should be checked for cascade requirements.booleanshouldCascadeParts()Flag used to determine if any parts should be cascadedbooleanshouldCascadePrivateParts()Flag used to determine if any private parts should be cascadedbooleanshouldCascadeReferences()Refreshes are based on the objects row, so all attributes of the object must be refreshed.booleanshouldForceCascade()This is used to cascade merge even if a clone is already registered.booleanshouldMergeChangesIntoDistributedCache()INTERNAL: This happens when changes from an UnitOfWork is propagated to a distributed class.booleanshouldMergeCloneIntoWorkingCopy()This can be used by the user for merging clones from RMI into the unit of work.booleanshouldMergeCloneWithReferencesIntoWorkingCopy()This can be used by the user for merging remote EJB objects into the unit of work.booleanshouldMergeOriginalIntoWorkingCopy()This is used to revert changes to objects, or during refreshes.booleanshouldMergeWorkingCopyIntoOriginal()This is used during the unit of work commit to merge changes into the parent.booleanshouldMergeWorkingCopyIntoRemote()INTERNAL: This happens when serialized remote unit of work has to be merged with local remote unit of work.booleanshouldRefreshRemoteObject()INTERNAL: This is used to refresh objects on the remote sessionvoidtransitionToDeferredLocks()INTERNAL: Records that this merge manager has transitioned to use deferred locks during the merge.protected voidupdateCacheKeyProperties(UnitOfWorkImpl unitOfWork, CacheKey cacheKey, Object original, Object clone, ObjectChangeSet objectChangeSet, ClassDescriptor descriptor)INTERNAL: Update CacheKey properties with new information.
-
-
-
Field Detail
-
session
protected AbstractSession session
The unit of work merging for.
-
objectDescriptors
protected Map<Object,ObjectDescriptor> objectDescriptors
Used only while refreshing objects on remote session
-
objectsAlreadyMerged
protected Map<AbstractSession,Map<Object,Object>> objectsAlreadyMerged
Used to unravel recursion.
-
mergedNewObjects
protected IdentityHashMap<Object,Object> mergedNewObjects
Used to keep track of merged new objects.
-
acquiredLocks
protected ArrayList<CacheKey> acquiredLocks
Used to store the list of locks that this merge manager has acquired for this merge
-
writeLockQueued
protected Object writeLockQueued
If this variable is not null then the mergemanager is waiting on a particular primary key
-
queueNode
protected LinkedNode queueNode
Stores the node that holds this mergemanager within the WriteLocksManager queue
-
mergePolicy
protected int mergePolicy
Policy that determines merge type (i.e. merge is used for several usages).
-
WORKING_COPY_INTO_ORIGINAL
protected static final int WORKING_COPY_INTO_ORIGINAL
- See Also:
- Constant Field Values
-
ORIGINAL_INTO_WORKING_COPY
protected static final int ORIGINAL_INTO_WORKING_COPY
- See Also:
- Constant Field Values
-
CLONE_INTO_WORKING_COPY
protected static final int CLONE_INTO_WORKING_COPY
- See Also:
- Constant Field Values
-
WORKING_COPY_INTO_REMOTE
protected static final int WORKING_COPY_INTO_REMOTE
- See Also:
- Constant Field Values
-
REFRESH_REMOTE_OBJECT
protected static final int REFRESH_REMOTE_OBJECT
- See Also:
- Constant Field Values
-
CHANGES_INTO_DISTRIBUTED_CACHE
protected static final int CHANGES_INTO_DISTRIBUTED_CACHE
- See Also:
- Constant Field Values
-
CLONE_WITH_REFS_INTO_WORKING_COPY
protected static final int CLONE_WITH_REFS_INTO_WORKING_COPY
- See Also:
- Constant Field Values
-
cascadePolicy
protected int cascadePolicy
Policy that determines how the merge will cascade to its object's parts.
-
NO_CASCADE
public static final int NO_CASCADE
- See Also:
- Constant Field Values
-
CASCADE_PRIVATE_PARTS
public static final int CASCADE_PRIVATE_PARTS
- See Also:
- Constant Field Values
-
CASCADE_ALL_PARTS
public static final int CASCADE_ALL_PARTS
- See Also:
- Constant Field Values
-
CASCADE_BY_MAPPING
public static final int CASCADE_BY_MAPPING
- See Also:
- Constant Field Values
-
LOCK_ON_MERGE
public static boolean LOCK_ON_MERGE
Backdoor to disable merge locks.
-
systemTime
protected long systemTime
Stored so that all objects merged by a merge manager can have the same readTime.
-
forceCascade
protected boolean forceCascade
Force cascade merge even if a clone is already registered
-
isTransitionedToDeferredLocks
protected boolean isTransitionedToDeferredLocks
records that deferred locks have been employed for the merge process
-
lockThread
protected Thread lockThread
save the currentThread for later comparison to the activeThread in case they don't match
-
isForRefresh
protected boolean isForRefresh
records that this merge process is for a refresh
-
-
Constructor Detail
-
MergeManager
public MergeManager(AbstractSession session)
-
-
Method Detail
-
cascadeAllParts
public void cascadeAllParts()
Cascade all parts, this is the default for the merge.
-
cascadePrivateParts
public void cascadePrivateParts()
Cascade private parts, this can be used to merge clone when using RMI.
-
dontCascadeParts
public void dontCascadeParts()
Merge only direct parts, this can be used to merge clone when using RMI.
-
getCascadePolicy
public int getCascadePolicy()
-
getMergePolicy
protected int getMergePolicy()
-
getObjectDescriptors
public Map<Object,ObjectDescriptor> getObjectDescriptors()
-
getObjectsAlreadyMerged
public Map<AbstractSession,Map<Object,Object>> getObjectsAlreadyMerged()
-
getObjectToMerge
public Object getObjectToMerge(Object sourceValue, ClassDescriptor descriptor, AbstractSession targetSession)
-
getQueueNode
public LinkedNode getQueueNode()
INTENRAL: Used to get the node that this merge manager is stored in, within the WriteLocksManager write lockers queue
-
getSession
public AbstractSession getSession()
-
getSystemTime
public long getSystemTime()
Get the stored value of the current time. This method lazily initializes so that read times for the same merge manager can all be set to the same read time
-
getTargetVersionOfSourceObject
public Object getTargetVersionOfSourceObject(Object source, ClassDescriptor descriptor, AbstractSession targetSession)
Return the corresponding value that should be assigned to the target object for the source object. This value must be local to the targets object space.
-
registerExistingObjectOfReadOnlyClassInNestedTransaction
public Object registerExistingObjectOfReadOnlyClassInNestedTransaction(Object source, ClassDescriptor descriptor, AbstractSession targetSession)
INTERNAL: Used to register an existing object used in nested unit of work with read-only class in root unit of work.
-
getWriteLockQueued
public Object getWriteLockQueued()
INTENRAL: Used to get the object that the merge manager is waiting on, in order to acquire locks
-
isForRefresh
public boolean isForRefresh()
- Returns:
- the isForMerge
-
setForRefresh
public void setForRefresh(boolean isforRefresh)
- Parameters:
isforRefresh- the isForMerge to set
-
isTransitionedToDeferredLocks
public boolean isTransitionedToDeferredLocks()
INTERNAL: Will return if the merge process has transitioned the active merge locks to deferred locks for readlock deadlock avoidance.
-
mergeChanges
public Object mergeChanges(Object object, ObjectChangeSet objectChangeSet, AbstractSession targetSession) throws ValidationException
Recursively merge changes in the object dependent on the merge policy. The map is used to resolve recursion.- Throws:
ValidationException
-
recordMerge
public void recordMerge(Object key, Object value, AbstractSession targetSession)
-
isAlreadyMerged
public boolean isAlreadyMerged(Object object, AbstractSession targetSession)
-
getMergedObject
public Object getMergedObject(Object key, AbstractSession targetSession)
-
mergeChangesForRefreshingRemoteObject
protected Object mergeChangesForRefreshingRemoteObject(Object serverSideDomainObject)
Recursively merge the RMI clone from the server into the client unit of work working copy. This will only be called if the working copy exists.
-
mergeChangesFromChangeSet
public void mergeChangesFromChangeSet(UnitOfWorkChangeSet uowChangeSet)
INTERNAL: Merge the changes to all objects to session's cache.
-
mergeChangesIntoDistributedCache
protected Object mergeChangesIntoDistributedCache(Object original, ObjectChangeSet changeSet)
Merge the changes specified within the changeSet into the cache. The object passed in is the original object from the cache.
-
mergeChangesOfCloneIntoWorkingCopy
protected Object mergeChangesOfCloneIntoWorkingCopy(Object rmiClone)
Recursively merge to rmi clone into the unit of work working copy. The map is used to resolve recursion.
-
mergeChangesOfOriginalIntoWorkingCopy
protected Object mergeChangesOfOriginalIntoWorkingCopy(Object clone)
Recursively merge to original from its parent into the clone. The map is used to resolve recursion.
-
mergeChangesOfWorkingCopyIntoOriginal
protected Object mergeChangesOfWorkingCopyIntoOriginal(Object clone, ObjectChangeSet objectChangeSet)
Recursively merge to clone into the original in its parent. The map is used to resolve recursion.
-
mergeChangesOfWorkingCopyIntoOriginal
protected CacheKey mergeChangesOfWorkingCopyIntoOriginal(Object clone, ObjectChangeSet objectChangeSet, ClassDescriptor descriptor, AbstractSession targetSession, UnitOfWorkImpl unitOfWork)
Recursively merge to clone into the original in its parent. The map is used to resolve recursion. This is used to merge objects from the unit of work into the shared (or isolated) cache.
-
mergeChangesOfWorkingCopyIntoRemote
public Object mergeChangesOfWorkingCopyIntoRemote(Object clone) throws ValidationException
Recursively merge changes in the object dependent on the merge policy. This merges changes from a remote unit of work back from the server into the original remote unit of work. This is meant to merge server-side changes such as sequence numbers, version numbers or events triggered changes.- Throws:
ValidationException
-
mergeCloneIntoWorkingCopy
public void mergeCloneIntoWorkingCopy()
This can be used by the user for merging clones from RMI into the unit of work.
-
mergeCloneWithReferencesIntoWorkingCopy
public void mergeCloneWithReferencesIntoWorkingCopy()
This is used during the merge of dependent objects referencing independent objects, where you want the independent objects merged as well.
-
mergeIntoDistributedCache
public void mergeIntoDistributedCache()
This is used during cache synchronization to merge the changes into the distributed cache.
-
mergeNewObjectIntoCache
public Object mergeNewObjectIntoCache(ObjectChangeSet changeSet)
Merge a change set for a new object into the cache. This method will create a shell for the new object and then merge the changes from the change set into the object. The newly merged object will then be added to the cache.
-
mergeOriginalIntoWorkingCopy
public void mergeOriginalIntoWorkingCopy()
This is used to revert changes to objects, or during refreshes.
-
mergeWorkingCopyIntoOriginal
public void mergeWorkingCopyIntoOriginal()
This is used during the unit of work commit to merge changes into the parent.
-
mergeWorkingCopyIntoRemote
public void mergeWorkingCopyIntoRemote()
This is used during the unit of work commit to merge changes into the parent.
-
refreshRemoteObject
public void refreshRemoteObject()
INTERNAL: This is used to refresh remote session object
-
registerObjectForMergeCloneIntoWorkingCopy
protected Object registerObjectForMergeCloneIntoWorkingCopy(Object clone, boolean shouldForceCascade)
INTERNAL: When merging from a clone when the cache cannot be guaranteed the object must be first read if it is existing and not in the cache. Otherwise no changes will be detected as the original state is missing.
-
checkNewObjectLockVersion
public void checkNewObjectLockVersion(Object clone, Object primaryKey, ClassDescriptor descriptor, UnitOfWorkImpl unitOfWork)
Check if the new object's version has been set, if so, then it was an existing object that was deleted. Raise an error instead of reincarnating the object.
-
registerRemovedNewObjectIfRequired
public void registerRemovedNewObjectIfRequired(Object removedObject)
Determine if the object is a registered new object, and that this is a nested unit of work merge into the parent. In this case private mappings will register the object as being removed.
-
setCascadePolicy
public void setCascadePolicy(int cascadePolicy)
-
setMergePolicy
protected void setMergePolicy(int mergePolicy)
-
setForceCascade
public void setForceCascade(boolean forceCascade)
-
setObjectDescriptors
public void setObjectDescriptors(Map<Object,ObjectDescriptor> objectDescriptors)
-
setObjectsAlreadyMerged
protected void setObjectsAlreadyMerged(Map<AbstractSession,Map<Object,Object>> objectsAlreadyMerged)
-
setQueueNode
public void setQueueNode(LinkedNode node)
INTENRAL: Used to set the node that this merge manager is stored in, within the WriteLocksManager write lockers queue
-
setSession
protected void setSession(AbstractSession session)
-
setWriteLockQueued
public void setWriteLockQueued(Object primaryKey)
INTENRAL: Used to set the object that the merge manager is waiting on, in order to acquire locks If this value is null then the merge manager is not waiting on any locks.
-
shouldCascadeByMapping
public boolean shouldCascadeByMapping()
Flag used to determine that the mappings should be checked for cascade requirements.
-
shouldCascadeAllParts
public boolean shouldCascadeAllParts()
Flag used to determine if all parts should be cascaded
-
shouldCascadeParts
public boolean shouldCascadeParts()
Flag used to determine if any parts should be cascaded
-
shouldCascadePrivateParts
public boolean shouldCascadePrivateParts()
Flag used to determine if any private parts should be cascaded
-
shouldCascadeReferences
public boolean shouldCascadeReferences()
Refreshes are based on the objects row, so all attributes of the object must be refreshed. However merging from RMI, normally reference are made transient, so should not be merge unless specified.
-
shouldMergeChangesIntoDistributedCache
public boolean shouldMergeChangesIntoDistributedCache()
INTERNAL: This happens when changes from an UnitOfWork is propagated to a distributed class.
-
shouldMergeCloneIntoWorkingCopy
public boolean shouldMergeCloneIntoWorkingCopy()
This can be used by the user for merging clones from RMI into the unit of work.
-
shouldMergeCloneWithReferencesIntoWorkingCopy
public boolean shouldMergeCloneWithReferencesIntoWorkingCopy()
This can be used by the user for merging remote EJB objects into the unit of work.
-
shouldMergeOriginalIntoWorkingCopy
public boolean shouldMergeOriginalIntoWorkingCopy()
This is used to revert changes to objects, or during refreshes.
-
shouldMergeWorkingCopyIntoOriginal
public boolean shouldMergeWorkingCopyIntoOriginal()
This is used during the unit of work commit to merge changes into the parent.
-
shouldMergeWorkingCopyIntoRemote
public boolean shouldMergeWorkingCopyIntoRemote()
INTERNAL: This happens when serialized remote unit of work has to be merged with local remote unit of work.
-
shouldRefreshRemoteObject
public boolean shouldRefreshRemoteObject()
INTERNAL: This is used to refresh objects on the remote session
-
shouldForceCascade
public boolean shouldForceCascade()
This is used to cascade merge even if a clone is already registered.
-
getMergedNewObjects
public IdentityHashMap<Object,Object> getMergedNewObjects()
INTERNAL: Used to return a map containing new objects found through the registerObjectForMergeCloneIntoWorkingCopy method.- Returns:
- Map
-
transitionToDeferredLocks
public void transitionToDeferredLocks()
INTERNAL: Records that this merge manager has transitioned to use deferred locks during the merge.
-
updateCacheKeyProperties
protected void updateCacheKeyProperties(UnitOfWorkImpl unitOfWork, CacheKey cacheKey, Object original, Object clone, ObjectChangeSet objectChangeSet, ClassDescriptor descriptor)
INTERNAL: Update CacheKey properties with new information. This method is called if this code actually merges
-
getLockThread
public Thread getLockThread()
INTERNAL:- Returns:
- lockThread
-
setLockThread
public void setLockThread(Thread lockThread)
INTERNAL: Save the currentThread for later comparison to the activeThread in case they don't match
-
-