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);
}
}
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);
}
}
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);
}
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;
}
Aggregations