Search in sources :

Example 1 with DirectMapChangeRecord

use of org.eclipse.persistence.internal.sessions.DirectMapChangeRecord in project eclipselink by eclipse-ee4j.

the class DirectMapMapping method updateChangeRecord.

/**
 * INTERNAL:
 * Either create a new change record or update the change record with the new value.
 * This is used by attribute change tracking.
 */
@Override
public void updateChangeRecord(Object clone, Object newValue, Object oldValue, ObjectChangeSet objectChangeSet, UnitOfWorkImpl uow) throws DescriptorException {
    DirectMapChangeRecord collectionChangeRecord = (DirectMapChangeRecord) objectChangeSet.getChangesForAttributeNamed(this.getAttributeName());
    if (collectionChangeRecord == null) {
        collectionChangeRecord = new DirectMapChangeRecord(objectChangeSet);
        collectionChangeRecord.setAttribute(getAttributeName());
        collectionChangeRecord.setMapping(this);
        objectChangeSet.addChange(collectionChangeRecord);
    }
    if (collectionChangeRecord.getOriginalCollection() == null) {
        collectionChangeRecord.recreateOriginalCollection(oldValue, uow);
    }
    collectionChangeRecord.setLatestCollection(newValue);
    collectionChangeRecord.setIsDeferred(true);
    objectChangeSet.deferredDetectionRequiredOn(getAttributeName());
}
Also used : DirectMapChangeRecord(org.eclipse.persistence.internal.sessions.DirectMapChangeRecord)

Example 2 with DirectMapChangeRecord

use of org.eclipse.persistence.internal.sessions.DirectMapChangeRecord in project eclipselink by eclipse-ee4j.

the class DirectMapMapping method addToCollectionChangeRecord.

/**
 * INTERNAL:
 * Add a new value and its change set to the collection change record.  This is used by
 * attribute change tracking.  If a value has changed then issue a remove first with the key
 * then an add.
 */
public void addToCollectionChangeRecord(Object newKey, Object newValue, ObjectChangeSet objectChangeSet, UnitOfWorkImpl uow) throws DescriptorException {
    DirectMapChangeRecord collectionChangeRecord = (DirectMapChangeRecord) objectChangeSet.getChangesForAttributeNamed(this.getAttributeName());
    if (collectionChangeRecord == null) {
        collectionChangeRecord = new DirectMapChangeRecord(objectChangeSet);
        collectionChangeRecord.setAttribute(getAttributeName());
        collectionChangeRecord.setMapping(this);
        objectChangeSet.addChange(collectionChangeRecord);
    }
    collectionChangeRecord.addAdditionChange(newKey, newValue);
}
Also used : DirectMapChangeRecord(org.eclipse.persistence.internal.sessions.DirectMapChangeRecord)

Example 3 with DirectMapChangeRecord

use of org.eclipse.persistence.internal.sessions.DirectMapChangeRecord 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 4 with DirectMapChangeRecord

use of org.eclipse.persistence.internal.sessions.DirectMapChangeRecord in project eclipselink by eclipse-ee4j.

the class DirectMapMapping method simpleRemoveFromCollectionChangeRecord.

/**
 * ADVANCED:
 * This method is used to have an object removed from a collection once the changeSet is applied
 * The referenceKey parameter should only be used for direct Maps.
 */
@Override
public void simpleRemoveFromCollectionChangeRecord(Object referenceKey, Object objectToRemove, ObjectChangeSet changeSet, AbstractSession session) {
    DirectMapChangeRecord collectionChangeRecord = (DirectMapChangeRecord) changeSet.getChangesForAttributeNamed(getAttributeName());
    if (collectionChangeRecord == null) {
        collectionChangeRecord = new DirectMapChangeRecord(changeSet);
        collectionChangeRecord.setAttribute(getAttributeName());
        collectionChangeRecord.setMapping(this);
        collectionChangeRecord.getRemoveObjects().put(referenceKey, objectToRemove);
        changeSet.addChange(collectionChangeRecord);
    } else {
        if (collectionChangeRecord.getAddObjects().containsKey(referenceKey)) {
            collectionChangeRecord.getAddObjects().remove(referenceKey);
        } else {
            collectionChangeRecord.getRemoveObjects().put(referenceKey, objectToRemove);
        }
    }
}
Also used : DirectMapChangeRecord(org.eclipse.persistence.internal.sessions.DirectMapChangeRecord)

Example 5 with DirectMapChangeRecord

use of org.eclipse.persistence.internal.sessions.DirectMapChangeRecord in project eclipselink by eclipse-ee4j.

the class DirectMapMapping method simpleAddToCollectionChangeRecord.

/**
 * ADVANCED:
 * This method is used to have an object add to a collection once the changeSet is applied
 * The referenceKey parameter should only be used for direct Maps.
 */
@Override
public void simpleAddToCollectionChangeRecord(Object referenceKey, Object objectToAdd, ObjectChangeSet changeSet, AbstractSession session) {
    DirectMapChangeRecord collectionChangeRecord = (DirectMapChangeRecord) changeSet.getChangesForAttributeNamed(getAttributeName());
    if (collectionChangeRecord == null) {
        collectionChangeRecord = new DirectMapChangeRecord(changeSet);
        collectionChangeRecord.setAttribute(getAttributeName());
        collectionChangeRecord.setMapping(this);
        collectionChangeRecord.getAddObjects().put(referenceKey, objectToAdd);
        changeSet.addChange(collectionChangeRecord);
    } else {
        if (collectionChangeRecord.getRemoveObjects().containsKey(referenceKey)) {
            collectionChangeRecord.getRemoveObjects().remove(referenceKey);
        } else {
            collectionChangeRecord.getAddObjects().put(referenceKey, objectToAdd);
        }
    }
}
Also used : DirectMapChangeRecord(org.eclipse.persistence.internal.sessions.DirectMapChangeRecord)

Aggregations

DirectMapChangeRecord (org.eclipse.persistence.internal.sessions.DirectMapChangeRecord)12 HashMap (java.util.HashMap)6 Map (java.util.Map)6 Iterator (java.util.Iterator)3 DescriptorIterator (org.eclipse.persistence.internal.descriptors.DescriptorIterator)3 ValueHolder (org.eclipse.persistence.indirection.ValueHolder)2 ObjectChangeSet (org.eclipse.persistence.internal.sessions.ObjectChangeSet)2 ChangeTracker (org.eclipse.persistence.descriptors.changetracking.ChangeTracker)1 MapChangeEvent (org.eclipse.persistence.descriptors.changetracking.MapChangeEvent)1 IndirectCollection (org.eclipse.persistence.indirection.IndirectCollection)1 AttributeChangeListener (org.eclipse.persistence.internal.descriptors.changetracking.AttributeChangeListener)1 ObjectChangeListener (org.eclipse.persistence.internal.descriptors.changetracking.ObjectChangeListener)1 DatabaseField (org.eclipse.persistence.internal.helper.DatabaseField)1 AbstractRecord (org.eclipse.persistence.internal.sessions.AbstractRecord)1 AbstractSession (org.eclipse.persistence.internal.sessions.AbstractSession)1