Search in sources :

Example 1 with DescriptorIterator

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);
}
Also used : DescriptorIterator(org.eclipse.persistence.internal.descriptors.DescriptorIterator) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping) CascadeCondition(org.eclipse.persistence.internal.descriptors.DescriptorIterator.CascadeCondition)

Example 2 with DescriptorIterator

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());
    }
}
Also used : DescriptorIterator(org.eclipse.persistence.internal.descriptors.DescriptorIterator) Iterator(java.util.Iterator) DescriptorIterator(org.eclipse.persistence.internal.descriptors.DescriptorIterator) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping)

Example 3 with DescriptorIterator

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());
    }
}
Also used : DescriptorIterator(org.eclipse.persistence.internal.descriptors.DescriptorIterator) EclipseLinkException(org.eclipse.persistence.exceptions.EclipseLinkException) Iterator(java.util.Iterator) DescriptorIterator(org.eclipse.persistence.internal.descriptors.DescriptorIterator)

Example 4 with DescriptorIterator

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());
            }
        }
    }
}
Also used : Enumeration(java.util.Enumeration) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) DescriptorIterator(org.eclipse.persistence.internal.descriptors.DescriptorIterator) IdentityMap(org.eclipse.persistence.internal.identitymaps.IdentityMap)

Example 5 with DescriptorIterator

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);
}
Also used : DescriptorIterator(org.eclipse.persistence.internal.descriptors.DescriptorIterator)

Aggregations

DescriptorIterator (org.eclipse.persistence.internal.descriptors.DescriptorIterator)5 Iterator (java.util.Iterator)2 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)2 Enumeration (java.util.Enumeration)1 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)1 EclipseLinkException (org.eclipse.persistence.exceptions.EclipseLinkException)1 CascadeCondition (org.eclipse.persistence.internal.descriptors.DescriptorIterator.CascadeCondition)1 IdentityMap (org.eclipse.persistence.internal.identitymaps.IdentityMap)1