use of org.eclipse.persistence.internal.descriptors.DescriptorIterator in project eclipselink by eclipse-ee4j.
the class UnitOfWorkImpl method unregisterObject.
/**
* INTERNAL:
* Unregister the object with the unit of work.
* This can be used to delete an object that was just created and is not yet persistent.
* Delete object can also be used, but will result in inserting the object and then deleting it.
*/
public void unregisterObject(Object clone, int cascadeDepth, boolean forDetach) {
// Allow register to be called with null and just return true
if (clone == null) {
return;
}
// CR#2272
logDebugMessage(clone, "unregister");
Object implementation = getDescriptor(clone).getObjectBuilder().unwrapObject(clone, this);
// This define an inner class for process the itteration operation, don't be scared, its just an inner class.
DescriptorIterator iterator = new DescriptorIterator() {
@Override
public void iterate(Object object) {
if (isClassReadOnly(object.getClass(), getCurrentDescriptor())) {
setShouldBreak(true);
return;
}
// Check if object exists in the IM.
Object primaryKey = getCurrentDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(object, UnitOfWorkImpl.this, true);
if (primaryKey != null) {
// If object exists in IM remove it from the IM and also from clone mapping.
getIdentityMapAccessorInstance().removeFromIdentityMap(primaryKey, object.getClass(), getCurrentDescriptor(), object);
}
getCloneMapping().remove(object);
// remove from deleted objects.
if (hasDeletedObjects()) {
getDeletedObjects().remove(object);
}
// PERF: Avoid initialization of new objects if none.
if (hasNewObjects()) {
Object original = getNewObjectsCloneToOriginal().remove(object);
if (original != null) {
getNewObjectsOriginalToClone().remove(original);
}
// Also need to remove the original merged object.
if (UnitOfWorkImpl.this.newObjectsCloneToMergeOriginal != null) {
original = UnitOfWorkImpl.this.newObjectsCloneToMergeOriginal.remove(object);
if (original != null) {
getNewObjectsOriginalToClone().remove(original);
}
}
}
}
};
iterator.setSession(this);
iterator.setCascadeDepth(cascadeDepth);
iterator.setForDetach(forDetach);
if (forDetach) {
CascadeCondition detached = iterator.new CascadeCondition() {
@Override
public boolean shouldNotCascade(DatabaseMapping mapping) {
return !(mapping.isForeignReferenceMapping() && ((ForeignReferenceMapping) mapping).isCascadeDetach());
}
};
iterator.setCascadeCondition(detached);
iterator.setShouldIterateOverUninstantiatedIndirectionObjects(false);
}
iterator.setShouldIterateOnFetchGroupAttributesOnly(true);
iterator.startIterationOn(implementation);
}
use of org.eclipse.persistence.internal.descriptors.DescriptorIterator in project eclipselink by eclipse-ee4j.
the class UnitOfWorkImpl method discoverUnregisteredNewObjects.
/**
* INTERNAL:
* Traverse the object to find references to objects not registered in this unit of work.
*/
public void discoverUnregisteredNewObjects(Map clones, final Map knownNewObjects, final Map unregisteredExistingObjects, Map visitedObjects) {
// This define an inner class for process the iteration operation, don't be scared, its just an inner class.
DescriptorIterator iterator = new DescriptorIterator() {
@Override
public void iterate(Object object) {
// If the object is read-only then do not continue the traversal.
if (isClassReadOnly(object.getClass(), this.getCurrentDescriptor())) {
this.setShouldBreak(true);
return;
}
/* CR3440: Steven Vo
* Include the case that object is original then do nothing.
*/
if (isSmartMerge() && isOriginalNewObject(object)) {
return;
} else if (!isObjectRegistered(object)) {
// Don't need to check for aggregates, as iterator does not iterate on them by default.
if (shouldPerformNoValidation()) {
if (checkForUnregisteredExistingObject(object)) {
// If no validation is performed and the object exists we need
// To keep a record of this object to ignore it, also I need to
// Stop iterating over it.
unregisteredExistingObjects.put(object, object);
this.setShouldBreak(true);
return;
}
} else {
// This will validate that the object is not from the parent session, moved from calculate to optimize JPA.
getBackupClone(object, getCurrentDescriptor());
}
// This means it is a unregistered new object
knownNewObjects.put(object, object);
}
}
@Override
public void iterateReferenceObjectForMapping(Object referenceObject, DatabaseMapping mapping) {
super.iterateReferenceObjectForMapping(referenceObject, mapping);
if (mapping.isCandidateForPrivateOwnedRemoval()) {
removePrivateOwnedObject(mapping, referenceObject);
}
}
};
// Bug 294259 - Do not replace the existingObjects list
iterator.setVisitedObjects(visitedObjects);
iterator.setResult(knownNewObjects);
iterator.setSession(this);
// When using wrapper policy in EJB the iteration should stop on beans,
// this is because EJB forces beans to be registered anyway and clone identity can be violated
// and the violated clones references to session objects should not be traversed.
iterator.setShouldIterateOverWrappedObjects(false);
for (Iterator clonesEnum = clones.keySet().iterator(); clonesEnum.hasNext(); ) {
iterator.startIterationOn(clonesEnum.next());
}
}
use of org.eclipse.persistence.internal.descriptors.DescriptorIterator in project eclipselink by eclipse-ee4j.
the class UnitOfWorkImpl method validateObjectSpace.
/**
* ADVANCED:
* This can be used to help debugging an object-space corruption.
* An object-space corruption is when your application has incorrectly related a clone to an original object.
* This method will validate that all registered objects are in a correct state and throw
* an error if not, it will contain the full stack of object references in the error message.
* If you call this method after each register or change you perform it will pin-point where the error was made.
*/
@Override
public void validateObjectSpace() {
log(SessionLog.FINER, SessionLog.TRANSACTION, "validate_object_space");
// This define an inner class for process the iteration operation, don't be scared, its just an inner class.
DescriptorIterator iterator = new DescriptorIterator() {
@Override
public void iterate(Object object) {
try {
if (isClassReadOnly(object.getClass(), getCurrentDescriptor())) {
setShouldBreak(true);
return;
} else {
getBackupClone(object, getCurrentDescriptor());
}
} catch (EclipseLinkException exception) {
log(SessionLog.FINEST, SessionLog.TRANSACTION, "stack_of_visited_objects_that_refer_to_the_corrupt_object", getVisitedStack());
log(SessionLog.FINER, SessionLog.TRANSACTION, "corrupt_object_referenced_through_mapping", getCurrentMapping());
throw exception;
}
}
};
iterator.setSession(this);
for (Iterator clonesEnum = getCloneMapping().keySet().iterator(); clonesEnum.hasNext(); ) {
iterator.startIterationOn(clonesEnum.next());
}
}
use of org.eclipse.persistence.internal.descriptors.DescriptorIterator in project eclipselink by eclipse-ee4j.
the class IdentityMapAccessor method validateCache.
/**
* INTERNAL:
* This can be used to help debugging an object identity problem.
* An object identity problem is when an object in the cache references an object not in the cache.
* This method will validate that all cached objects are in a correct state.
*/
@Override
public void validateCache() {
// pass certain calls to this in order to allow subclasses to implement own behavior
getSession().log(SessionLog.FINER, SessionLog.CACHE, "validate_cache");
// This define an inner class for process the iteration operation, don't be scared, its just an inner class.
DescriptorIterator iterator = new DescriptorIterator() {
@Override
public void iterate(Object object) {
if (!containsObjectInIdentityMap(IdentityMapAccessor.this.session.getDescriptor(object.getClass()).getObjectBuilder().extractPrimaryKeyFromObject(object, IdentityMapAccessor.this.getSession()), object.getClass())) {
IdentityMapAccessor.this.session.log(SessionLog.FINEST, SessionLog.CACHE, "stack_of_visited_objects_that_refer_to_the_corrupt_object", getVisitedStack());
IdentityMapAccessor.this.session.log(SessionLog.FINER, SessionLog.CACHE, "corrupt_object_referenced_through_mapping", getCurrentMapping());
IdentityMapAccessor.this.session.log(SessionLog.FINER, SessionLog.CACHE, "corrupt_object", object);
}
}
};
iterator.setSession(getSession());
Iterator<ClassDescriptor> descriptors = getSession().getDescriptors().values().iterator();
while (descriptors.hasNext()) {
ClassDescriptor descriptor = descriptors.next();
IdentityMap cache = getIdentityMap(descriptor, true);
if (cache != null) {
for (Enumeration mapEnum = cache.elements(); mapEnum.hasMoreElements(); ) {
iterator.startIterationOn(mapEnum.nextElement());
}
}
}
}
use of org.eclipse.persistence.internal.descriptors.DescriptorIterator in project eclipselink by eclipse-ee4j.
the class RemoteSessionController method replaceValueHoldersIn.
/**
* Traverse the specified object, replacing the standard
* value holders with remote value holders.
* Add the resulting object descriptors to the
* "collecting parm".
*/
public void replaceValueHoldersIn(Object object, Map objectDescriptors) {
if (object == null) {
return;
}
DescriptorIterator iterator = new ReplaceValueHoldersIterator(this);
iterator.setResult(objectDescriptors);
iterator.setSession(getExecutionSession());
// process the value holders themselves
iterator.setShouldIterateOnIndirectionObjects(true);
// but don't go beyond them
iterator.setShouldIterateOverIndirectionObjects(false);
iterator.startIterationOn(object);
}
Aggregations