Search in sources :

Example 1 with ObjectChangeListener

use of org.eclipse.persistence.internal.descriptors.changetracking.ObjectChangeListener in project eclipselink by eclipse-ee4j.

the class ObjectReferenceMapping method mergeIntoObject.

/**
 * INTERNAL:
 * Merge changes from the source to the target object.
 */
@Override
public void mergeIntoObject(Object target, boolean isTargetUnInitialized, Object source, MergeManager mergeManager, AbstractSession targetSession) {
    if (this.descriptor.getCachePolicy().isProtectedIsolation() && !this.isCacheable && !targetSession.isProtectedSession()) {
        setAttributeValueInObject(target, this.indirectionPolicy.buildIndirectObject(new ValueHolder<>(null)));
        return;
    }
    if (isTargetUnInitialized) {
        // or for new objects.
        if (mergeManager.shouldMergeWorkingCopyIntoOriginal()) {
            if (!isAttributeValueInstantiated(source)) {
                setAttributeValueInObject(target, this.indirectionPolicy.getOriginalIndirectionObject(getAttributeValueFromObject(source), targetSession));
                return;
            } else {
                // Must clear the old value holder to cause it to be reset.
                this.indirectionPolicy.reset(target);
            }
        }
    }
    if (!shouldMergeCascadeReference(mergeManager)) {
        // This is only going to happen on mergeClone, and we should not attempt to merge the reference
        return;
    }
    if (mergeManager.shouldRefreshRemoteObject() && usesIndirection()) {
        mergeRemoteValueHolder(target, source, mergeManager);
        return;
    }
    if (mergeManager.isForRefresh()) {
        if (!isAttributeValueInstantiated(target)) {
            // the refresh that attribute
            if (shouldRefreshCascadeParts(mergeManager)) {
                Object attributeValue = getAttributeValueFromObject(source);
                Integer refreshCascade = null;
                if (selectionQuery != null && selectionQuery.isObjectBuildingQuery() && ((ObjectBuildingQuery) selectionQuery).shouldRefreshIdentityMapResult()) {
                    refreshCascade = selectionQuery.getCascadePolicy();
                }
                // building clone from an original not a row.
                Object clonedAttributeValue = this.indirectionPolicy.cloneAttribute(attributeValue, source, null, target, refreshCascade, mergeManager.getSession(), false);
                setAttributeValueInObject(target, clonedAttributeValue);
            }
            return;
        }
    } else if (!isAttributeValueInstantiated(source)) {
        // modified
        return;
    }
    Object valueOfSource = getRealAttributeValueFromObject(source, mergeManager.getSession());
    Object targetValueOfSource = null;
    // another thread can pick up the partial object.
    if (shouldMergeCascadeParts(mergeManager) && (valueOfSource != null)) {
        if ((mergeManager.getSession().isUnitOfWork()) && (((UnitOfWorkImpl) mergeManager.getSession()).getUnitOfWorkChangeSet() != null)) {
            // If it is a unit of work, we have to check if I have a change Set fot this object
            Object targetValue = mergeManager.mergeChanges(mergeManager.getObjectToMerge(valueOfSource, referenceDescriptor, targetSession), (ObjectChangeSet) ((UnitOfWorkImpl) mergeManager.getSession()).getUnitOfWorkChangeSet().getObjectChangeSetForClone(valueOfSource), targetSession);
            if (target == source && targetValue != valueOfSource && (this.descriptor.getObjectChangePolicy().isObjectChangeTrackingPolicy()) && (target instanceof ChangeTracker) && (((ChangeTracker) target)._persistence_getPropertyChangeListener() != null)) {
                ObjectChangeListener listener = (ObjectChangeListener) ((ChangeTracker) target)._persistence_getPropertyChangeListener();
                if (listener != null) {
                    // update the ChangeSet recorded within the parents ObjectChangeSet as the parent is referenceing the ChangeSet
                    // for a detached or new Entity.
                    this.descriptor.getObjectChangePolicy().updateListenerForSelfMerge(listener, this, valueOfSource, targetValue, (UnitOfWorkImpl) mergeManager.getSession());
                }
            }
        } else {
            mergeManager.mergeChanges(mergeManager.getObjectToMerge(valueOfSource, referenceDescriptor, targetSession), null, targetSession);
        }
    }
    if (valueOfSource != null) {
        // Need to do this after merge so that an object exists in the database
        targetValueOfSource = mergeManager.getTargetVersionOfSourceObject(valueOfSource, referenceDescriptor, targetSession);
    }
    // If merge into the unit of work, must only merge and raise the event is the value changed.
    if ((mergeManager.shouldMergeCloneIntoWorkingCopy() || mergeManager.shouldMergeCloneWithReferencesIntoWorkingCopy()) && !mergeManager.isForRefresh() && this.descriptor.getObjectChangePolicy().isObjectChangeTrackingPolicy()) {
        // Object level or attribute level so lets see if we need to raise the event?
        Object valueOfTarget = getRealAttributeValueFromObject(target, mergeManager.getSession());
        if (valueOfTarget != targetValueOfSource) {
            // equality comparison cause both are uow clones
            this.descriptor.getObjectChangePolicy().raiseInternalPropertyChangeEvent(target, getAttributeName(), valueOfTarget, targetValueOfSource);
        } else {
            // No change.
            return;
        }
    }
    targetValueOfSource = this.referenceDescriptor.getObjectBuilder().wrapObject(targetValueOfSource, mergeManager.getSession());
    setRealAttributeValueInObject(target, targetValueOfSource);
}
Also used : ObjectChangeListener(org.eclipse.persistence.internal.descriptors.changetracking.ObjectChangeListener) ValueHolder(org.eclipse.persistence.indirection.ValueHolder) DatabaseValueHolder(org.eclipse.persistence.internal.indirection.DatabaseValueHolder) ChangeTracker(org.eclipse.persistence.descriptors.changetracking.ChangeTracker)

Example 2 with ObjectChangeListener

use of org.eclipse.persistence.internal.descriptors.changetracking.ObjectChangeListener in project eclipselink by eclipse-ee4j.

the class DirectMapMapping method mergeIntoObject.

/**
 * INTERNAL:
 * Merge changes from the source to the target object.
 */
@Override
public void mergeIntoObject(Object target, boolean isTargetUnInitialized, Object source, MergeManager mergeManager, AbstractSession targetSession) {
    if (this.descriptor.getCachePolicy().isProtectedIsolation() && !this.isCacheable && !targetSession.isProtectedSession()) {
        setAttributeValueInObject(target, this.indirectionPolicy.buildIndirectObject(new ValueHolder<>(null)));
        return;
    }
    if (isTargetUnInitialized) {
        // This will happen if the target object was removed from the cache before the commit was attempted
        if (mergeManager.shouldMergeWorkingCopyIntoOriginal() && (!isAttributeValueInstantiated(source))) {
            setAttributeValueInObject(target, getIndirectionPolicy().getOriginalIndirectionObject(getAttributeValueFromObject(source), targetSession));
            return;
        }
    }
    if (!shouldMergeCascadeReference(mergeManager)) {
        // This is only going to happen on mergeClone, and we should not attempt to merge the reference
        return;
    }
    if (mergeManager.shouldRefreshRemoteObject() && usesIndirection()) {
        mergeRemoteValueHolder(target, source, mergeManager);
        return;
    }
    if (mergeManager.isForRefresh()) {
        if (!isAttributeValueInstantiated(target)) {
            // the refresh that attribute
            return;
        }
    } else if (!isAttributeValueInstantiated(source)) {
        // modified
        return;
    }
    Map valueOfSource = (Map) getRealCollectionAttributeValueFromObject(source, mergeManager.getSession());
    // trigger instantiation of target attribute
    Object valueOfTarget = getRealCollectionAttributeValueFromObject(target, mergeManager.getSession());
    Object newContainer = containerPolicy.containerInstance(containerPolicy.sizeFor(valueOfSource));
    boolean fireChangeEvents = false;
    if ((this.getDescriptor().getObjectChangePolicy().isObjectChangeTrackingPolicy()) && (target instanceof ChangeTracker) && (((ChangeTracker) target)._persistence_getPropertyChangeListener() != null)) {
        fireChangeEvents = true;
        // Collections may not be indirect list or may have been replaced with user collection.
        Object iterator = containerPolicy.iteratorFor(valueOfTarget);
        while (containerPolicy.hasNext(iterator)) {
            Map.Entry entry = (Map.Entry) containerPolicy.nextEntry(iterator, mergeManager.getSession());
            // make the remove change event fire.
            ((ObjectChangeListener) ((ChangeTracker) target)._persistence_getPropertyChangeListener()).internalPropertyChange(new MapChangeEvent(target, getAttributeName(), valueOfTarget, entry.getKey(), entry.getValue(), CollectionChangeEvent.REMOVE, false));
        }
        if (newContainer instanceof ChangeTracker) {
            ((ChangeTracker) newContainer)._persistence_setPropertyChangeListener(((ChangeTracker) target)._persistence_getPropertyChangeListener());
        }
        if (valueOfTarget instanceof ChangeTracker) {
            // remove listener
            ((ChangeTracker) valueOfTarget)._persistence_setPropertyChangeListener(null);
        }
    }
    valueOfTarget = newContainer;
    for (Object sourceValuesIterator = containerPolicy.iteratorFor(valueOfSource); containerPolicy.hasNext(sourceValuesIterator); ) {
        Map.Entry entry = (Map.Entry) containerPolicy.nextEntry(sourceValuesIterator, mergeManager.getSession());
        if (fireChangeEvents) {
            // Collections may not be indirect list or may have been replaced with user collection.
            // make the add change event fire.
            ((ObjectChangeListener) ((ChangeTracker) target)._persistence_getPropertyChangeListener()).internalPropertyChange(new MapChangeEvent(target, getAttributeName(), valueOfTarget, entry.getKey(), entry.getValue(), CollectionChangeEvent.ADD, false));
        }
        containerPolicy.addInto(entry.getKey(), entry.getValue(), valueOfTarget, mergeManager.getSession());
    }
    if (fireChangeEvents && (getDescriptor().getObjectChangePolicy().isAttributeChangeTrackingPolicy())) {
        // check that there were changes, if not then remove the record.
        ObjectChangeSet changeSet = ((AttributeChangeListener) ((ChangeTracker) target)._persistence_getPropertyChangeListener()).getObjectChangeSet();
        if (changeSet != null) {
            DirectMapChangeRecord changeRecord = (DirectMapChangeRecord) changeSet.getChangesForAttributeNamed(getAttributeName());
            if (changeRecord != null) {
                if (!changeRecord.isDeferred()) {
                    if (!changeRecord.hasChanges()) {
                        changeSet.removeChange(getAttributeName());
                    }
                } else {
                    // Must reset the latest collection.
                    changeRecord.setLatestCollection(valueOfTarget);
                }
            }
        }
    }
    // Must re-set variable to allow for set method to re-morph changes if the collection is not being stored directly.
    setRealAttributeValueInObject(target, valueOfTarget);
}
Also used : DirectMapChangeRecord(org.eclipse.persistence.internal.sessions.DirectMapChangeRecord) AttributeChangeListener(org.eclipse.persistence.internal.descriptors.changetracking.AttributeChangeListener) ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) ObjectChangeListener(org.eclipse.persistence.internal.descriptors.changetracking.ObjectChangeListener) ValueHolder(org.eclipse.persistence.indirection.ValueHolder) MapChangeEvent(org.eclipse.persistence.descriptors.changetracking.MapChangeEvent) Map(java.util.Map) HashMap(java.util.HashMap) ChangeTracker(org.eclipse.persistence.descriptors.changetracking.ChangeTracker)

Example 3 with ObjectChangeListener

use of org.eclipse.persistence.internal.descriptors.changetracking.ObjectChangeListener in project eclipselink by eclipse-ee4j.

the class ObjectChangeTrackingPolicy method setChangeListener.

/**
 * INTERNAL:
 * Assign ObjectChangeListener to PropertyChangeListener
 */
@Override
public PropertyChangeListener setChangeListener(Object clone, UnitOfWorkImpl uow, ClassDescriptor descriptor) {
    ObjectChangeListener listener = new ObjectChangeListener();
    ((ChangeTracker) clone)._persistence_setPropertyChangeListener(listener);
    return listener;
}
Also used : AggregateObjectChangeListener(org.eclipse.persistence.internal.descriptors.changetracking.AggregateObjectChangeListener) ObjectChangeListener(org.eclipse.persistence.internal.descriptors.changetracking.ObjectChangeListener)

Example 4 with ObjectChangeListener

use of org.eclipse.persistence.internal.descriptors.changetracking.ObjectChangeListener in project eclipselink by eclipse-ee4j.

the class ObjectChangeTrackingPolicy method clearChanges.

/**
 * INTERNAL:
 * Clear the changes in the ObjectChangeListener
 */
@Override
public void clearChanges(Object clone, UnitOfWorkImpl uow, ClassDescriptor descriptor, boolean forRefresh) {
    ObjectChangeListener listener = (ObjectChangeListener) ((ChangeTracker) clone)._persistence_getPropertyChangeListener();
    if (listener != null) {
        listener.clearChanges(forRefresh);
    } else {
        listener = (ObjectChangeListener) setChangeListener(clone, uow, descriptor);
    }
    ObjectBuilder builder = descriptor.getObjectBuilder();
    // Only relationship mappings need to be reset.
    if (!builder.isSimple()) {
        dissableEventProcessing(clone);
        // Must also ensure the listener has been set on collections and aggregates.
        FetchGroupManager fetchGroupManager = descriptor.getFetchGroupManager();
        boolean isPartialObject = (fetchGroupManager != null) && fetchGroupManager.isPartialObject(clone);
        List<DatabaseMapping> mappings = builder.getRelationshipMappings();
        int size = mappings.size();
        // Only cascade fetched mappings.
        for (int index = 0; index < size; index++) {
            DatabaseMapping mapping = mappings.get(index);
            if (!isPartialObject || fetchGroupManager.isAttributeFetched(clone, mapping.getAttributeName())) {
                mapping.setChangeListener(clone, listener, uow);
            }
        }
        enableEventProcessing(clone);
    }
}
Also used : FetchGroupManager(org.eclipse.persistence.descriptors.FetchGroupManager) AggregateObjectChangeListener(org.eclipse.persistence.internal.descriptors.changetracking.AggregateObjectChangeListener) ObjectChangeListener(org.eclipse.persistence.internal.descriptors.changetracking.ObjectChangeListener) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping) ObjectBuilder(org.eclipse.persistence.internal.descriptors.ObjectBuilder)

Example 5 with ObjectChangeListener

use of org.eclipse.persistence.internal.descriptors.changetracking.ObjectChangeListener in project eclipselink by eclipse-ee4j.

the class ObjectChangeTrackingPolicy method shouldCompareExistingObjectForChange.

/**
 * INTERNAL:
 * Return true if the Object should be compared, false otherwise.  In ObjectChangeTrackingPolicy or
 * AttributeChangeTracking Policy this method will return true if the object is new, if the object
 * is in the OptimisticReadLock list or if the listener.hasChanges() returns true.
 * @param object the object that will be compared
 * @param unitOfWork the active unitOfWork
 * @param descriptor the descriptor for the current object
 */
@Override
public boolean shouldCompareExistingObjectForChange(Object object, UnitOfWorkImpl unitOfWork, ClassDescriptor descriptor) {
    // PERF: Breakdown the logic to have the most likely scenario checked first
    ObjectChangeListener listener = (ObjectChangeListener) ((ChangeTracker) object)._persistence_getPropertyChangeListener();
    if ((listener != null) && listener.hasChanges()) {
        return true;
    }
    Boolean optimisticRead = null;
    if (unitOfWork.hasOptimisticReadLockObjects()) {
        optimisticRead = (Boolean) unitOfWork.getOptimisticReadLockObjects().get(object);
        // updated (opt. read lock and forceUpdate)
        if (optimisticRead != null) {
            return true;
        }
    }
    if ((descriptor.getCMPPolicy() != null) && descriptor.getCMPPolicy().getForceUpdate()) {
        return true;
    }
    return false;
}
Also used : AggregateObjectChangeListener(org.eclipse.persistence.internal.descriptors.changetracking.AggregateObjectChangeListener) ObjectChangeListener(org.eclipse.persistence.internal.descriptors.changetracking.ObjectChangeListener)

Aggregations

ObjectChangeListener (org.eclipse.persistence.internal.descriptors.changetracking.ObjectChangeListener)6 ChangeTracker (org.eclipse.persistence.descriptors.changetracking.ChangeTracker)3 ValueHolder (org.eclipse.persistence.indirection.ValueHolder)3 AggregateObjectChangeListener (org.eclipse.persistence.internal.descriptors.changetracking.AggregateObjectChangeListener)3 AttributeChangeListener (org.eclipse.persistence.internal.descriptors.changetracking.AttributeChangeListener)2 ObjectChangeSet (org.eclipse.persistence.internal.sessions.ObjectChangeSet)2 PropertyChangeEvent (java.beans.PropertyChangeEvent)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 FetchGroupManager (org.eclipse.persistence.descriptors.FetchGroupManager)1 CollectionChangeEvent (org.eclipse.persistence.descriptors.changetracking.CollectionChangeEvent)1 MapChangeEvent (org.eclipse.persistence.descriptors.changetracking.MapChangeEvent)1 ObjectBuilder (org.eclipse.persistence.internal.descriptors.ObjectBuilder)1 DatabaseValueHolder (org.eclipse.persistence.internal.indirection.DatabaseValueHolder)1 ContainerPolicy (org.eclipse.persistence.internal.queries.ContainerPolicy)1 OrderedListContainerPolicy (org.eclipse.persistence.internal.queries.OrderedListContainerPolicy)1 DirectCollectionChangeRecord (org.eclipse.persistence.internal.sessions.DirectCollectionChangeRecord)1 DirectMapChangeRecord (org.eclipse.persistence.internal.sessions.DirectMapChangeRecord)1 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)1