/** * Flag used to determine that the mappings should be checked for * cascade requirements. */ public boolean shouldCascadeByMapping() { return getCascadePolicy() == CASCADE_BY_MAPPING; }
/** * INTERNAL: * This happens when changes from an UnitOfWork is propagated to a distributed class. */ public boolean shouldMergeChangesIntoDistributedCache() { return getMergePolicy() == CHANGES_INTO_DISTRIBUTED_CACHE; }
/** * INTERNAL: * Cascade the merge to the component object, if appropriate. */ public void cascadeMerge(Object sourceElement, MergeManager mergeManager) { if (shouldMergeCascadeParts(mergeManager)) { mergeManager.mergeChanges(mergeManager.getObjectToMerge(sourceElement), null); } }
/** * Recursively merge changes in the object dependent on the merge policy. * The hastable is used to resolv recursion. */ public Object mergeChanges(Object object, ObjectChangeSet objectChangeSet) throws ValidationException { if (object == null) { return object; } // Do not merged read-only objects in a unit of work. if (getSession().isClassReadOnly(object.getClass())) { return object; } // Means that object is either already merged or in the process of being merged. if (getObjectsAlreadyMerged().containsKey(object)) { return object; } // Put the object to be merged in the set. getObjectsAlreadyMerged().put(object, object); Object mergedObject; if (shouldMergeWorkingCopyIntoOriginal()) { mergedObject = mergeChangesOfWorkingCopyIntoOriginal(object, objectChangeSet); } else if (shouldMergeCloneIntoWorkingCopy() || shouldMergeCloneWithReferencesIntoWorkingCopy()) { mergedObject = mergeChangesOfCloneIntoWorkingCopy(object); } else if (shouldMergeOriginalIntoWorkingCopy()) { mergedObject = mergeChangesOfOriginalIntoWorkingCopy(object); } else { throw ValidationException.invalidMergePolicy(); } return mergedObject; }
/** * Return the coresponding value that should be assigned to the target object for the source object. * This value must be local to the targets object space. */ public Object getTargetVersionOfSourceObject(Object source) { if (shouldMergeWorkingCopyIntoOriginal() || shouldMergeWorkingCopyIntoRemote()) { // Target is in uow parent, or original instance for new object. return ((UnitOfWorkImpl)getSession()).getOriginalVersionOfObject(source); } else if (shouldMergeCloneIntoWorkingCopy() || shouldMergeOriginalIntoWorkingCopy() || shouldMergeCloneWithReferencesIntoWorkingCopy()) { // Target is clone from uow. //make sure we use the register for merge //bug 3584343 return registerObjectForMergeCloneIntoWorkingCopy(source); } else if (shouldRefreshRemoteObject()) { // Target is in session's cache. ClassDescriptor descriptor = getSession().getDescriptor(source); Vector primaryKey = descriptor.getObjectBuilder().extractPrimaryKeyFromObject(source, getSession()); return getSession().getIdentityMapAccessorInstance().getFromIdentityMap(primaryKey, source.getClass(), descriptor); } throw ValidationException.invalidMergePolicy(); }
if (isTargetUnInitialized) { if (mergeManager.shouldMergeWorkingCopyIntoOriginal() && (!isAttributeValueInstantiated(source))) { setAttributeValueInObject(target, getIndirectionPolicy().getOriginalIndirectionObject(getAttributeValueFromObject(source), mergeManager.getSession())); return; if (mergeManager.shouldMergeOriginalIntoWorkingCopy()) { if (!isAttributeValueInstantiated(target)) { Object valueOfSource = getRealAttributeValueFromObject(source, mergeManager.getSession()); if ((mergeManager.getSession().isUnitOfWork()) && (((UnitOfWorkImpl)mergeManager.getSession()).getUnitOfWorkChangeSet() != null)) { mergeManager.mergeChanges(mergeManager.getObjectToMerge(valueOfSource), (ObjectChangeSet)((UnitOfWorkChangeSet)((UnitOfWorkImpl)mergeManager.getSession()).getUnitOfWorkChangeSet()).getObjectChangeSetForClone(valueOfSource)); } else { mergeManager.mergeChanges(mergeManager.getObjectToMerge(valueOfSource), null); targetValueOfSource = mergeManager.getTargetVersionOfSourceObject(valueOfSource); Object valueOfTarget = getRealAttributeValueFromObject(target, mergeManager.getSession()); if ( valueOfTarget != targetValueOfSource ) { //equality comparison cause both are uow clones this.getDescriptor().getObjectChangePolicy().raiseInternalPropertyChangeEvent(target, getAttributeName(), valueOfTarget, targetValueOfSource); targetValueOfSource = getReferenceDescriptor().getObjectBuilder().wrapObject(targetValueOfSource, mergeManager.getSession()); setRealAttributeValueInObject(target, targetValueOfSource);
Object object = null; if (mergeManager.shouldMergeChangesIntoDistributedCache()) { if (!mergeManager.getObjectsAlreadyMerged().containsKey(objectChanges)) { Class objectClass = objectChanges.getClassType(mergeManager.getSession()); object = mergeManager.getSession().getDescriptor(objectClass).getObjectBuilder().buildNewInstance(); mergeManager.getObjectsAlreadyMerged().put(objectChanges, object); } else { object = mergeManager.getObjectsAlreadyMerged().get(objectChanges); mergeManager.mergeChanges(object, objectChanges); mergeManager.mergeChanges(objectChanges.getUnitOfWorkClone(), objectChanges);
AbstractSession session = mergeManager.getSession(); if (session.isUnitOfWork()) { session = ((UnitOfWorkImpl)session).getParent(); mergeManager.getAcquiredLocks().add(activeCacheKey); } else { params[1] = Thread.currentThread().getName(); session.log(SessionLog.FINER, SessionLog.CACHE, "dead_lock_encountered_on_write", params, null, true); if (mergeManager.getWriteLockQueued() == null) { mergeManager.setQueueNode(this.prevailingQueue.addLast(mergeManager)); mergeManager.setWriteLockQueued(objectChangeSet.getCacheKey()); try { mergeManager.getAcquiredLocks().add(activeCacheKey); throw exception; } finally { if (mergeManager.getWriteLockQueued() != null) { this.prevailingQueue.remove(mergeManager.getQueueNode()); mergeManager.setWriteLockQueued(null);
IdentityHashtable backupSet = buildIdentitySet(backup, containerPolicy, false); IdentityHashtable sourceSet = null; IdentityHashtable targetToSources = null; if (shouldMergeWorkingCopyIntoOriginal()) { sourceSet = buildIdentitySet(source, containerPolicy, false); } else { targetToSources = buildIdentitySet(source, containerPolicy, true); Object backupElement = containerPolicy.next(backupIter, getSession()); if (shouldMergeWorkingCopyIntoOriginal()) {// Source and backup are the same space. if (!sourceSet.containsKey(backupElement)) { changeOccured = true; containerPolicy.removeFrom((Object)null, getTargetVersionOfSourceObject(backupElement), target, getSession()); registerRemovedNewObjectIfRequired(backupElement); if (!targetToSources.containsKey(backupElement)) {// If no source for target then was removed. changeOccured = true; containerPolicy.removeFrom((Object)null, backupElement, target, getSession());// Backup value is same as target value. Object sourceElement = containerPolicy.next(sourceIter, getSession()); if (shouldMergeWorkingCopyIntoOriginal()) {// Source and backup are the same space. if (!backupSet.containsKey(sourceElement)) { changeOccured = true; containerPolicy.addInto(getTargetVersionOfSourceObject(sourceElement), target, getSession()); } else {
Object implementation = builder.unwrapObject(rmiClone, this); MergeManager manager = new MergeManager(this); manager.mergeCloneWithReferencesIntoWorkingCopy(); manager.setCascadePolicy(cascadePolicy); manager.setForceCascade(forceCascade); Object mergedObject = manager.mergeChanges(implementation, null); if (isSmartMerge()) { return builder.wrapObject(mergedObject, this);
valueOfTarget = containerPolicy.containerInstance(changeRecord.getAddObjectList().size()); } else { valueOfTarget = getRealCollectionAttributeValueFromObject(target, mergeManager.getSession()); if (mergeManager.getSession().isUnitOfWork() && !mergeManager.shouldMergeWorkingCopyIntoBackup()) { parentSession = ((UnitOfWorkImpl)mergeManager.getSession()).getParent(); } else { parentSession = mergeManager.getSession(); } else { if (mergeManager.shouldMergeChangesIntoDistributedCache()) { return; // do nothing valueOfSource = getRealCollectionAttributeValueFromObject(source, mergeManager.getSession()); Object iterator = containerPolicy.iteratorFor(valueOfSource); valueOfTarget = containerPolicy.containerInstance(containerPolicy.sizeFor(valueOfSource)); Object objectToMerge = containerPolicy.next(iterator, mergeManager.getSession()); mergeManager.mergeChanges(objectToMerge, changeSet); containerPolicy.addInto(mergeManager.getTargetVersionOfSourceObject(objectToMerge), valueOfTarget, mergeManager.getSession());
if (isTargetUnInitialized) { if (mergeManager.shouldMergeWorkingCopyIntoOriginal() && (!isAttributeValueInstantiated(source))) { setAttributeValueInObject(target, getIndirectionPolicy().getOriginalIndirectionObject(getAttributeValueFromObject(source), mergeManager.getSession())); return; if (mergeManager.shouldMergeOriginalIntoWorkingCopy()) { if (!isAttributeValueInstantiated(target)) { Map valueOfSource = (Map)getRealCollectionAttributeValueFromObject(source, mergeManager.getSession()); Object valueOfTarget = getRealCollectionAttributeValueFromObject(target, mergeManager.getSession()); Object newContainer = containerPolicy.containerInstance(containerPolicy.sizeFor(valueOfSource)); Object sourceKey = containerPolicy.next(sourceValuesIterator, mergeManager.getSession()); containerPolicy.addInto(sourceKey, valueOfSource.get(sourceKey), valueOfTarget, mergeManager.getSession());
/** * INTERNAL: * Revert the object's attributes from the parent. * This uses merging to merge the object changes. */ public Object revertObject(Object clone, int cascadeDepth) { if (clone == null) { return null; } //CR#2272 logDebugMessage(clone, "revert"); ClassDescriptor descriptor = getDescriptor(clone); ObjectBuilder builder = descriptor.getObjectBuilder(); Object implementation = builder.unwrapObject(clone, this); MergeManager manager = new MergeManager(this); manager.mergeOriginalIntoWorkingCopy(); manager.setCascadePolicy(cascadeDepth); try { manager.mergeChanges(implementation, null); } catch (RuntimeException exception) { return handleException(exception); } return clone; }
if (changeSet.isNew()) { Class objectClass = changeSet.getClassType(session); ClassDescriptor descriptor = getSession().getDescriptor(objectClass); Object object = changeSet.getTargetVersionOfSourceObject(getSession(), false); if (object == null) { if (!getObjectsAlreadyMerged().containsKey(changeSet)) { getObjectsAlreadyMerged().put(changeSet, object); } else { object = getObjectsAlreadyMerged().get(changeSet); object = changeSet.getTargetVersionOfSourceObject(getSession(), true); mergeChanges(object, changeSet); Object implementation = descriptor.getObjectBuilder().unwrapObject(object, getSession()); return getSession().getIdentityMapAccessorInstance().putInIdentityMap(implementation, descriptor.getObjectBuilder().extractPrimaryKeyFromObject(implementation, getSession()), changeSet.getWriteLockValue(), getSystemTime(), descriptor);
/** * INTERNAL: * Merge the attributes of the clone into the unit of work copy. */ public Object mergeClone(Object rmiClone, int cascadeDepth) { if (rmiClone == null) { return null; } //CR#2272 logDebugMessage(rmiClone, "merge_clone"); startOperationProfile(SessionProfiler.Merge); ObjectBuilder builder = getDescriptor(rmiClone).getObjectBuilder(); Object implementation = builder.unwrapObject(rmiClone, this); MergeManager manager = new MergeManager(this); manager.mergeCloneIntoWorkingCopy(); manager.setCascadePolicy(cascadeDepth); Object merged = null; try { merged = manager.mergeChanges(implementation, null); } catch (RuntimeException exception) { merged = handleException(exception); } endOperationProfile(SessionProfiler.Merge); return merged; }
MergeManager manager = new MergeManager(this); manager.mergeOriginalIntoWorkingCopy(); manager.cascadeAllParts(); for (Enumeration cloneEnum = getCloneMapping().keys(); cloneEnum.hasMoreElements();) { Object clone = cloneEnum.nextElement(); manager.mergeChanges(clone, null); ClassDescriptor descriptor = this.getDescriptor(clone);
removeFrom(objectChanges.getOldKey(), objectChanges.getTargetVersionOfSourceObject(mergeManager.getSession()), valueOfTarget, parentSession); registerRemoveNewObjectIfRequired(objectChanges, mergeManager); object = objectChanges.getTargetVersionOfSourceObject(mergeManager.getSession()); if (objectAdded && mergeManager.shouldMergeChangesIntoDistributedCache()) { if (! contains(object, valueOfTarget, mergeManager.getSession())) { addIntoAtIndex(changeRecord.getOrderedAddObjectIndex(objectChanges), object, valueOfTarget, mergeManager.getSession()); addIntoAtIndex(changeRecord.getOrderedAddObjectIndex(objectChanges), object, valueOfTarget, mergeManager.getSession());
getSession().startOperationProfile(SessionProfiler.DistributedMerge); getSession().getIdentityMapAccessorInstance().acquireWriteLock(); getSession().log(SessionLog.FINER, SessionLog.PROPAGATION, "received_updates_from_remote_server"); getSession().getEventManager().preDistributedMergeUnitOfWorkChangeSet(uowChangeSet); getSession().getIdentityMapAccessorInstance().getWriteLockManager().acquireRequiredLocks(this, uowChangeSet); Enumeration objectChangeEnum = uowChangeSet.getAllChangeSets().keys(); while (objectChangeEnum.hasMoreElements()) { ObjectChangeSet objectChangeSet = (ObjectChangeSet)objectChangeEnum.nextElement(); Object object = objectChangeSet.getTargetVersionOfSourceObject(getSession(), false); Object mergedObject = this.mergeChanges(object, objectChangeSet); mergedObject = mergeNewObjectIntoCache(objectChangeSet); getSession().incrementProfile(SessionProfiler.ChangeSetsNotProcessed); } else { getSession().incrementProfile(SessionProfiler.ChangeSetsProcessed); while (deletedObjects.hasMoreElements()) { ObjectChangeSet changeSet = (ObjectChangeSet)deletedObjects.nextElement(); changeSet.removeFromIdentityMap(getSession()); getSession().incrementProfile(SessionProfiler.DeletedObject); getSession().handleException(exception); } finally { getSession().getIdentityMapAccessorInstance().getWriteLockManager().releaseAllAcquiredLocks(this); getSession().getIdentityMapAccessorInstance().releaseWriteLock();
removeFrom(objectChanges.getOldKey(), objectChanges.getTargetVersionOfSourceObject(mergeManager.getSession()), valueOfTarget, parentSession); if (!mergeManager.shouldMergeChangesIntoDistributedCache()) { mergeManager.registerRemovedNewObjectIfRequired(objectChanges.getUnitOfWorkClone()); object = objectChanges.getTargetVersionOfSourceObject(mergeManager.getSession(), false); if (mergeManager.shouldMergeChangesIntoDistributedCache()) { if (!contains(object, valueOfTarget, mergeManager.getSession())) { addInto(objectChanges.getNewKey(), object, valueOfTarget, mergeManager.getSession()); addInto(objectChanges.getNewKey(), object, valueOfTarget, mergeManager.getSession());
ClassDescriptor descriptor = getSession().getDescriptor(rmiClone); Object registeredObject = registerObjectForMergeCloneIntoWorkingCopy(rmiClone); if (registeredObject == rmiClone && !shouldForceCascade()) {