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