Search in sources :

Example 1 with AggregateCollectionChangeRecord

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

the class AggregateCollectionMapping 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.  PLEASE ENSURE that the changes
 * have been made in the object model first.
 */
@Override
public void simpleRemoveFromCollectionChangeRecord(Object referenceKey, Object changeSetToRemove, ObjectChangeSet changeSet, AbstractSession session) {
    AggregateCollectionChangeRecord collectionChangeRecord = (AggregateCollectionChangeRecord) changeSet.getChangesForAttributeNamed(this.getAttributeName());
    if (collectionChangeRecord == null) {
        // if there is no change for this attribute then create a changeSet for it. no need to modify the resulting
        // change record as it should be built from the clone which has the changes allready
        Object cloneObject = changeSet.getUOWChangeSet().getUOWCloneForObjectChangeSet(changeSet);
        Object cloneCollection = this.getRealAttributeValueFromObject(cloneObject, session);
        collectionChangeRecord = (AggregateCollectionChangeRecord) convertToChangeRecord(cloneCollection, containerPolicy.containerInstance(), changeSet, session);
        changeSet.addChange(collectionChangeRecord);
    } else {
        collectionChangeRecord.getChangedValues().remove(changeSetToRemove);
    }
}
Also used : AggregateCollectionChangeRecord(org.eclipse.persistence.internal.sessions.AggregateCollectionChangeRecord)

Example 2 with AggregateCollectionChangeRecord

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

the class AggregateCollectionMapping 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. PLEASE ENSURE that the changes
 * have been made in the object model first.
 */
@Override
public void simpleAddToCollectionChangeRecord(Object referenceKey, Object changeSetToAdd, ObjectChangeSet changeSet, AbstractSession session) {
    AggregateCollectionChangeRecord collectionChangeRecord = (AggregateCollectionChangeRecord) changeSet.getChangesForAttributeNamed(this.getAttributeName());
    if (collectionChangeRecord == null) {
        // if there is no change for this attribute then create a changeSet for it. no need to modify the resulting
        // change record as it should be built from the clone which has the changes allready
        Object cloneObject = changeSet.getUOWChangeSet().getUOWCloneForObjectChangeSet(changeSet);
        Object cloneCollection = this.getRealAttributeValueFromObject(cloneObject, session);
        collectionChangeRecord = (AggregateCollectionChangeRecord) convertToChangeRecord(cloneCollection, containerPolicy.containerInstance(), changeSet, session);
        changeSet.addChange(collectionChangeRecord);
    } else {
        collectionChangeRecord.getChangedValues().add((ObjectChangeSet) changeSetToAdd);
    }
}
Also used : AggregateCollectionChangeRecord(org.eclipse.persistence.internal.sessions.AggregateCollectionChangeRecord)

Example 3 with AggregateCollectionChangeRecord

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

the class AggregateCollectionMapping method mergeChangesIntoObject.

/**
 * INTERNAL:
 * Merge changes from the source to the target object.
 * Because this is a collection mapping, values are added to or removed from the
 * collection based on the changeset
 */
@Override
public void mergeChangesIntoObject(Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager, AbstractSession targetSession) {
    if (this.descriptor.getCachePolicy().isProtectedIsolation() && !this.isCacheable && !targetSession.isProtectedSession()) {
        setAttributeValueInObject(target, this.indirectionPolicy.buildIndirectObject(new ValueHolder<>(null)));
        return;
    }
    // Check to see if the target has an instantiated collection
    if (!isAttributeValueInstantiatedOrChanged(target)) {
        // Then do nothing.
        return;
    }
    ContainerPolicy containerPolicy = getContainerPolicy();
    AbstractSession session = mergeManager.getSession();
    Object valueOfTarget = null;
    // At this point the source's indirection must be instantiated or the changeSet would never have
    // been created
    Object sourceAggregate = null;
    // find the originals for merging and indirection information may be lost.
    if (mergeManager.shouldMergeChangesIntoDistributedCache()) {
        ClassDescriptor descriptor = getDescriptor();
        AbstractRecord parentRow = descriptor.getObjectBuilder().extractPrimaryKeyRowFromObject(target, session);
        // fix for indirection
        Object result = getIndirectionPolicy().valueFromQuery(getSelectionQuery(), parentRow, session);
        setAttributeValueInObject(target, result);
        return;
    }
    // iterate over the changes and merge the collections
    List<ObjectChangeSet> aggregateObjects = ((AggregateCollectionChangeRecord) changeRecord).getChangedValues();
    int size = aggregateObjects.size();
    valueOfTarget = containerPolicy.containerInstance(size);
    // Next iterate over the changes and add them to the container
    ObjectChangeSet objectChanges = null;
    for (int index = 0; index < size; ++index) {
        objectChanges = aggregateObjects.get(index);
        Class<?> localClassType = objectChanges.getClassType(session);
        sourceAggregate = objectChanges.getUnitOfWorkClone();
        // cr 4155 Load the target from the UnitOfWork.  This will be the original
        // aggregate object that has the original indirection in it.
        Object targetAggregate = ((UnitOfWorkImpl) mergeManager.getSession()).getCloneToOriginals().get(sourceAggregate);
        if (targetAggregate == null) {
            targetAggregate = getReferenceDescriptor(localClassType, session).getObjectBuilder().buildNewInstance();
        }
        getReferenceDescriptor(localClassType, session).getObjectBuilder().mergeChangesIntoObject(targetAggregate, objectChanges, sourceAggregate, mergeManager, targetSession);
        containerPolicy.addInto(objectChanges.getNewKey(), targetAggregate, valueOfTarget, session);
    }
    setRealAttributeValueInObject(target, valueOfTarget);
}
Also used : ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord) ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) ValueHolder(org.eclipse.persistence.indirection.ValueHolder) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession) AggregateCollectionChangeRecord(org.eclipse.persistence.internal.sessions.AggregateCollectionChangeRecord)

Example 4 with AggregateCollectionChangeRecord

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

the class AggregateCollectionMapping method convertToChangeRecord.

/**
 * INTERNAL:
 * This method is used to convert the contents of an aggregateCollection into a
 * changeRecord
 * @return org.eclipse.persistence.internal.sessions.AggregateCollectionChangeRecord the changerecord representing this AggregateCollectionMapping
 * @param owner org.eclipse.persistence.internal.sessions.ObjectChangeSet the ChangeSet that uses this record
 * @param cloneCollection Object the collection to convert
 * @param session org.eclipse.persistence.internal.sessions.AbstractSession
 */
protected ChangeRecord convertToChangeRecord(Object cloneCollection, Object backupCollection, ObjectChangeSet owner, AbstractSession session) {
    ContainerPolicy cp = getContainerPolicy();
    Object cloneIter = cp.iteratorFor(cloneCollection);
    Vector collectionChanges = new Vector(2);
    while (cp.hasNext(cloneIter)) {
        Object entry = cp.nextEntry(cloneIter, session);
        Object aggregateObject = cp.unwrapIteratorResult(entry);
        // For CR#2258 quietly ignore nulls inserted into a collection.
        if (aggregateObject != null) {
            ObjectChangeSet changes = getReferenceDescriptor(aggregateObject.getClass(), session).getObjectBuilder().compareForChange(aggregateObject, null, (UnitOfWorkChangeSet) owner.getUOWChangeSet(), session);
            changes.setNewKey(cp.keyFromIterator(cloneIter));
            collectionChanges.addElement(changes);
        }
    }
    // cr 3013 Removed if collection is empty return null block, which prevents recording clear() change
    AggregateCollectionChangeRecord changeRecord = new AggregateCollectionChangeRecord(owner);
    changeRecord.setAttribute(getAttributeName());
    changeRecord.setMapping(this);
    changeRecord.setChangedValues(collectionChanges);
    changeRecord.setOriginalCollection(backupCollection);
    getContainerPolicy().compareCollectionsForChange(backupCollection, cloneCollection, changeRecord, session, remoteReferenceDescriptor);
    return changeRecord;
}
Also used : ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) Vector(java.util.Vector) NonSynchronizedVector(org.eclipse.persistence.internal.helper.NonSynchronizedVector) AggregateCollectionChangeRecord(org.eclipse.persistence.internal.sessions.AggregateCollectionChangeRecord)

Aggregations

AggregateCollectionChangeRecord (org.eclipse.persistence.internal.sessions.AggregateCollectionChangeRecord)4 ContainerPolicy (org.eclipse.persistence.internal.queries.ContainerPolicy)2 ObjectChangeSet (org.eclipse.persistence.internal.sessions.ObjectChangeSet)2 Vector (java.util.Vector)1 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)1 ValueHolder (org.eclipse.persistence.indirection.ValueHolder)1 NonSynchronizedVector (org.eclipse.persistence.internal.helper.NonSynchronizedVector)1 AbstractRecord (org.eclipse.persistence.internal.sessions.AbstractRecord)1 AbstractSession (org.eclipse.persistence.internal.sessions.AbstractSession)1