Search in sources :

Example 16 with FetchGroupManager

use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.

the class ObjectChangeSet method getOldValue.

public Object getOldValue(AbstractSession session) {
    if (this.isNew) {
        return null;
    }
    if (this.changes == null || this.changes.isEmpty()) {
        // object has not changed
        return this.cloneObject;
    } else {
        if (this.cloneObject != null && session != null) {
            Object oldValue = this.descriptor.getObjectBuilder().buildNewInstance();
            FetchGroup fetchGroup = null;
            FetchGroupManager fetchGroupManager = this.descriptor.getFetchGroupManager();
            if (fetchGroupManager != null) {
                fetchGroup = fetchGroupManager.getObjectFetchGroup(this.cloneObject);
            }
            for (DatabaseMapping mapping : this.descriptor.getMappings()) {
                String attributeName = mapping.getAttributeName();
                if (fetchGroup == null || fetchGroup.containsAttributeInternal(attributeName)) {
                    ChangeRecord changeRecord = (ChangeRecord) getChangesForAttributeNamed(attributeName);
                    if (changeRecord != null) {
                        mapping.setRealAttributeValueInObject(oldValue, changeRecord.getOldValue());
                    } else {
                        mapping.setAttributeValueInObject(oldValue, mapping.getAttributeValueFromObject(this.cloneObject));
                    }
                }
            }
            return oldValue;
        }
    }
    return null;
}
Also used : FetchGroupManager(org.eclipse.persistence.descriptors.FetchGroupManager) FetchGroup(org.eclipse.persistence.queries.FetchGroup) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping)

Example 17 with FetchGroupManager

use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.

the class ObjectBuilder method buildBackupClone.

/**
 * Returns the backup clone of the specified object. This is called only from unit of work.
 * The clone sent as parameter is always a working copy from the unit of work.
 */
public Object buildBackupClone(Object clone, UnitOfWorkImpl unitOfWork) {
    // The copy policy builds clone    .
    ClassDescriptor descriptor = this.descriptor;
    Object backup = descriptor.getCopyPolicy().buildClone(clone, unitOfWork);
    // PERF: Avoid synchronized enumerator as is concurrency bottleneck.
    List<DatabaseMapping> mappings = getCloningMappings();
    int size = mappings.size();
    if (descriptor.hasFetchGroupManager() && descriptor.getFetchGroupManager().isPartialObject(clone)) {
        FetchGroupManager fetchGroupManager = descriptor.getFetchGroupManager();
        for (int index = 0; index < size; index++) {
            DatabaseMapping mapping = mappings.get(index);
            if (fetchGroupManager.isAttributeFetched(clone, mapping.getAttributeName())) {
                mapping.buildBackupClone(clone, backup, unitOfWork);
            }
        }
    } else {
        for (int index = 0; index < size; index++) {
            mappings.get(index).buildBackupClone(clone, backup, unitOfWork);
        }
    }
    return backup;
}
Also used : FetchGroupManager(org.eclipse.persistence.descriptors.FetchGroupManager) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) InvalidObject(org.eclipse.persistence.internal.helper.InvalidObject) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping)

Example 18 with FetchGroupManager

use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.

the class ObjectBuilder method copyObject.

/**
 * Return a copy of the object.
 * This is NOT used for unit of work but for templatizing an object.
 * The depth and primary key reseting are passed in.
 */
public Object copyObject(Object original, CopyGroup copyGroup) {
    Object copy = copyGroup.getCopies().get(original);
    if (copyGroup.shouldCascadeTree()) {
        FetchGroupManager fetchGroupManager = this.descriptor.getFetchGroupManager();
        if (fetchGroupManager != null) {
            // empty copy group means all the attributes should be copied - don't alter it.
            if (copyGroup.hasItems()) {
                // by default add primary key attribute(s) if not already in the group
                if (!copyGroup.shouldResetPrimaryKey()) {
                    for (DatabaseMapping mapping : this.primaryKeyMappings) {
                        String name = mapping.getAttributeName();
                        if (!copyGroup.containsAttributeInternal(name)) {
                            copyGroup.addAttribute(name);
                        }
                    }
                } else {
                    for (DatabaseMapping mapping : this.primaryKeyMappings) {
                        if (mapping.isForeignReferenceMapping()) {
                            String name = mapping.getAttributeName();
                            if (!copyGroup.containsAttributeInternal(name)) {
                                copyGroup.addAttribute(name);
                            }
                        }
                    }
                }
                // by default version attribute if not already in the group
                if (!copyGroup.shouldResetVersion()) {
                    if (this.lockAttribute != null) {
                        if (!copyGroup.containsAttributeInternal(this.lockAttribute)) {
                            copyGroup.addAttribute(this.lockAttribute);
                        }
                    }
                }
                FetchGroup fetchGroup = fetchGroupManager.getObjectFetchGroup(original);
                if (fetchGroup != null) {
                    if (!fetchGroup.getAttributeNames().containsAll(copyGroup.getAttributeNames())) {
                        // trigger fetch group if it does not contain all attributes of the copy group.
                        fetchGroup.onUnfetchedAttribute((FetchGroupTracker) original, null);
                    }
                }
            }
            // Entity fetch group currently set on copyObject
            EntityFetchGroup existingEntityFetchGroup = null;
            if (copy != null) {
                Object[] copyArray = (Object[]) copy;
                // copy of the original
                copy = copyArray[0];
                // A set of CopyGroups that have visited.
                Set<CopyGroup> visitedCopyGroups = (Set<CopyGroup>) copyArray[1];
                if (visitedCopyGroups.contains(copyGroup)) {
                    // original has been already visited with this copyGroup - leave
                    return copy;
                } else {
                    visitedCopyGroups.add(copyGroup);
                }
                existingEntityFetchGroup = fetchGroupManager.getObjectEntityFetchGroup(copy);
            }
            // Entity fetch group that will be assigned to copyObject
            EntityFetchGroup newEntityFetchGroup = null;
            // Attributes to be visited - only reference mappings will be visited.
            // If null then all attributes should be visited.
            Set<String> attributesToVisit = copyGroup.getAttributeNames();
            // Attributes to be copied
            Set<String> attributesToCopy = attributesToVisit;
            boolean shouldCopyAllAttributes = false;
            boolean shouldAssignNewEntityFetchGroup = false;
            if (copy != null && existingEntityFetchGroup == null) {
                // all attributes have been already copied
                attributesToCopy = null;
            } else {
                // Entity fetch group corresponding to copyPolicy.
                // Note that empty, or null, or containing all arguments attributesToCopy
                // results in copyGroupFetchGroup = null;
                EntityFetchGroup copyGroupEntityFetchGroup = fetchGroupManager.getEntityFetchGroup(attributesToCopy);
                if (copyGroupEntityFetchGroup == null) {
                    // all attributes will be copied
                    shouldCopyAllAttributes = true;
                }
                if (copy != null) {
                    if (copyGroupEntityFetchGroup != null) {
                        if (!copyGroup.shouldResetPrimaryKey()) {
                            if (!existingEntityFetchGroup.getAttributeNames().containsAll(attributesToCopy)) {
                                // Entity fetch group that will be assigned to copy object
                                newEntityFetchGroup = fetchGroupManager.flatUnionFetchGroups(existingEntityFetchGroup, copyGroupEntityFetchGroup, false);
                                shouldAssignNewEntityFetchGroup = true;
                            }
                        }
                        attributesToCopy = new HashSet(attributesToCopy);
                        attributesToCopy.removeAll(existingEntityFetchGroup.getAttributeNames());
                    }
                } else {
                    // copy does not exist - create it
                    copy = copyGroup.getSession().getDescriptor(original).getObjectBuilder().buildNewInstance();
                    Set<CopyGroup> visitedCopyGroups = new HashSet();
                    visitedCopyGroups.add(copyGroup);
                    copyGroup.getCopies().put(original, new Object[] { copy, visitedCopyGroups });
                    if (!copyGroup.shouldResetPrimaryKey()) {
                        newEntityFetchGroup = copyGroupEntityFetchGroup;
                        shouldAssignNewEntityFetchGroup = true;
                    }
                }
            }
            if (shouldAssignNewEntityFetchGroup) {
                fetchGroupManager.setObjectFetchGroup(copy, newEntityFetchGroup, null);
            }
            for (DatabaseMapping mapping : getDescriptor().getMappings()) {
                String name = mapping.getAttributeName();
                boolean shouldCopy = shouldCopyAllAttributes || (attributesToCopy != null && attributesToCopy.contains(name));
                boolean shouldVisit = attributesToVisit == null || attributesToVisit.contains(name);
                if (shouldCopy || shouldVisit) {
                    boolean isVisiting = false;
                    // unless it's a reference mapping pass copyGroup - just to carry the session.
                    CopyGroup mappingCopyGroup = copyGroup;
                    if (mapping.isForeignReferenceMapping()) {
                        ForeignReferenceMapping frMapping = (ForeignReferenceMapping) mapping;
                        ClassDescriptor referenceDescriptor = frMapping.getReferenceDescriptor();
                        if (referenceDescriptor != null) {
                            isVisiting = true;
                            mappingCopyGroup = copyGroup.getGroup(name);
                            if (mappingCopyGroup == null) {
                                FetchGroupManager referenceFetchGroupManager = referenceDescriptor.getFetchGroupManager();
                                if (referenceFetchGroupManager != null) {
                                    EntityFetchGroup nonReferenceEntityFetchGroup = referenceFetchGroupManager.getNonReferenceEntityFetchGroup(copyGroup.shouldResetPrimaryKey(), copyGroup.shouldResetVersion());
                                    if (nonReferenceEntityFetchGroup != null) {
                                        mappingCopyGroup = nonReferenceEntityFetchGroup.toCopyGroup();
                                    } else {
                                        // null nonReferenceEntityFetchGroup is equivalent to containing all attributes:
                                        // create a new empty CopyGroup.
                                        mappingCopyGroup = new CopyGroup();
                                        mappingCopyGroup.shouldCascadeTree();
                                    }
                                } else {
                                    // TODO: would that work?
                                    mappingCopyGroup = new CopyGroup();
                                    mappingCopyGroup.dontCascade();
                                    isVisiting = false;
                                }
                                mappingCopyGroup.setCopies(copyGroup.getCopies());
                                mappingCopyGroup.setShouldResetPrimaryKey(copyGroup.shouldResetPrimaryKey());
                                mappingCopyGroup.setShouldResetVersion(copyGroup.shouldResetVersion());
                            }
                            mappingCopyGroup.setSession(copyGroup.getSession());
                        }
                    } else if (mapping.isAggregateObjectMapping()) {
                        mappingCopyGroup = new CopyGroup();
                    }
                    if (shouldCopy || isVisiting) {
                        // TODO: optimization: (even when isVisiting == true) redefine buildCopy to take shouldCopy and don't copy if not required.
                        mapping.buildCopy(copy, original, mappingCopyGroup);
                    }
                }
            }
        } else {
        // fetchGroupManager == null
        // TODO
        }
    } else {
        // ! copyGroup.shouldCascadeTree()
        if (copy != null) {
            return copy;
        }
        copy = instantiateClone(original, copyGroup.getSession());
        copyGroup.getCopies().put(original, copy);
        // PERF: Avoid synchronized enumerator as is concurrency bottleneck.
        List<DatabaseMapping> mappings = getCloningMappings();
        int size = mappings.size();
        for (int index = 0; index < size; index++) {
            mappings.get(index).buildCopy(copy, original, copyGroup);
        }
        if (copyGroup.shouldResetPrimaryKey() && (!(this.descriptor.isDescriptorTypeAggregate()))) {
            // Do not reset if any of the keys is mapped through a 1-1, i.e. back reference id has already changed.
            boolean hasOneToOne = false;
            List<DatabaseMapping> primaryKeyMappings = getPrimaryKeyMappings();
            size = primaryKeyMappings.size();
            for (int index = 0; index < size; index++) {
                if (primaryKeyMappings.get(index).isOneToOneMapping()) {
                    hasOneToOne = true;
                }
            }
            if (!hasOneToOne) {
                for (int index = 0; index < size; index++) {
                    DatabaseMapping mapping = primaryKeyMappings.get(index);
                    // Only null out direct mappings, as others will be nulled in the respective objects.
                    if (mapping.isAbstractColumnMapping()) {
                        Object nullValue = ((AbstractColumnMapping) mapping).getObjectValue(null, copyGroup.getSession());
                        mapping.setAttributeValueInObject(copy, nullValue);
                    } else if (mapping.isTransformationMapping()) {
                        mapping.setAttributeValueInObject(copy, null);
                    }
                }
            }
        }
        // PERF: Avoid events if no listeners.
        if (this.descriptor.getEventManager().hasAnyEventListeners()) {
            org.eclipse.persistence.descriptors.DescriptorEvent event = new org.eclipse.persistence.descriptors.DescriptorEvent(copy);
            event.setSession(copyGroup.getSession());
            event.setOriginalObject(original);
            event.setEventCode(DescriptorEventManager.PostCloneEvent);
            this.descriptor.getEventManager().executeEvent(event);
        }
    }
    return copy;
}
Also used : EntityFetchGroup(org.eclipse.persistence.internal.queries.EntityFetchGroup) FetchGroupManager(org.eclipse.persistence.descriptors.FetchGroupManager) AggregateObjectChangeSet(org.eclipse.persistence.internal.sessions.AggregateObjectChangeSet) ResultSet(java.sql.ResultSet) ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) Set(java.util.Set) UnitOfWorkChangeSet(org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet) IdentityHashSet(org.eclipse.persistence.internal.helper.IdentityHashSet) HashSet(java.util.HashSet) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) DescriptorEvent(org.eclipse.persistence.descriptors.DescriptorEvent) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping) DescriptorEvent(org.eclipse.persistence.descriptors.DescriptorEvent) AbstractColumnMapping(org.eclipse.persistence.mappings.foundation.AbstractColumnMapping) ForeignReferenceMapping(org.eclipse.persistence.mappings.ForeignReferenceMapping) CopyGroup(org.eclipse.persistence.sessions.CopyGroup) FetchGroup(org.eclipse.persistence.queries.FetchGroup) EntityFetchGroup(org.eclipse.persistence.internal.queries.EntityFetchGroup) InvalidObject(org.eclipse.persistence.internal.helper.InvalidObject) IdentityHashSet(org.eclipse.persistence.internal.helper.IdentityHashSet) HashSet(java.util.HashSet)

Example 19 with FetchGroupManager

use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.

the class WriteLockManager method traverseRelatedLocks.

/**
 * INTERNAL:
 * Traverse the object and acquire locks on all related objects.
 */
public CacheKey traverseRelatedLocks(Object objectForClone, Map lockedObjects, Map refreshedObjects, ClassDescriptor descriptor, AbstractSession cloningSession) {
    // If all mappings have indirection short-circuit.
    if (descriptor.shouldAcquireCascadedLocks()) {
        FetchGroupManager fetchGroupManager = descriptor.getFetchGroupManager();
        boolean isPartialObject = (fetchGroupManager != null) && fetchGroupManager.isPartialObject(objectForClone);
        for (Iterator<DatabaseMapping> mappings = descriptor.getLockableMappings().iterator(); mappings.hasNext(); ) {
            DatabaseMapping mapping = mappings.next();
            // Only cascade fetched mappings.
            if (!isPartialObject || (fetchGroupManager.isAttributeFetched(objectForClone, mapping.getAttributeName()))) {
                // any mapping in this list must not have indirection.
                Object objectToLock = mapping.getAttributeValueFromObject(objectForClone);
                if (mapping.isCollectionMapping()) {
                    // Ignore null, means empty.
                    if (objectToLock != null) {
                        ContainerPolicy cp = mapping.getContainerPolicy();
                        Object iterator = cp.iteratorFor(objectToLock);
                        while (cp.hasNext(iterator)) {
                            Object object = cp.next(iterator, cloningSession);
                            if (mapping.getReferenceDescriptor().hasWrapperPolicy()) {
                                object = mapping.getReferenceDescriptor().getWrapperPolicy().unwrapObject(object, cloningSession);
                            }
                            CacheKey toWaitOn = checkAndLockObject(object, lockedObjects, refreshedObjects, mapping, cloningSession);
                            if (toWaitOn != null) {
                                return toWaitOn;
                            }
                        }
                    }
                } else {
                    if (mapping.getReferenceDescriptor().hasWrapperPolicy()) {
                        objectToLock = mapping.getReferenceDescriptor().getWrapperPolicy().unwrapObject(objectToLock, cloningSession);
                    }
                    CacheKey toWaitOn = checkAndLockObject(objectToLock, lockedObjects, refreshedObjects, mapping, cloningSession);
                    if (toWaitOn != null) {
                        return toWaitOn;
                    }
                }
            }
        }
    }
    return null;
}
Also used : ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) FetchGroupManager(org.eclipse.persistence.descriptors.FetchGroupManager) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping) CacheKey(org.eclipse.persistence.internal.identitymaps.CacheKey)

Example 20 with FetchGroupManager

use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.

the class AdvancedFetchGroupJunitTest method testVerifyFetchGroups.

public void testVerifyFetchGroups() {
    if (isWeavingEnabled()) {
        ClassDescriptor hockeyGearDescriptor = getServerSession().getDescriptor(HockeyGear.class);
        FetchGroupManager hockeyGearFetchGroupManager = hockeyGearDescriptor.getFetchGroupManager();
        assertTrue("Wrong number of fetch groups for HockeyGear", hockeyGearFetchGroupManager.getFetchGroups().size() == 1);
        assertNotNull("The 'MSRP' fetch group was not found for HockeyGear", hockeyGearFetchGroupManager.getFetchGroup("MSRP"));
        ClassDescriptor padsDescriptor = getServerSession().getDescriptor(Pads.class);
        FetchGroupManager padsFetchGroupManager = padsDescriptor.getFetchGroupManager();
        assertTrue("Wrong number of fetch groups for Pads", padsFetchGroupManager.getFetchGroups().size() == 3);
        assertNotNull("The 'HeightAndWidth' fetch group was not found for Pads", padsFetchGroupManager.getFetchGroup("HeightAndWidth"));
        assertNotNull("The 'Weight' fetch group was not found for Pads", padsFetchGroupManager.getFetchGroup("Weight"));
        assertNotNull("The 'AgeGroup' fetch group was not found for Pads", padsFetchGroupManager.getFetchGroup("AgeGroup"));
        ClassDescriptor chestProtectorDescriptor = getServerSession().getDescriptor(ChestProtector.class);
        FetchGroupManager chestProtectorFetchGroupManager = chestProtectorDescriptor.getFetchGroupManager();
        assertTrue("Wrong number of fetch groups for ChestProtector", chestProtectorFetchGroupManager.getFetchGroups().size() == 1);
        assertNotNull("The 'AgeGroup' fetch group was not found for ChestProtector", chestProtectorFetchGroupManager.getFetchGroup("AgeGroup"));
    }
}
Also used : FetchGroupManager(org.eclipse.persistence.descriptors.FetchGroupManager) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor)

Aggregations

FetchGroupManager (org.eclipse.persistence.descriptors.FetchGroupManager)27 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)13 FetchGroup (org.eclipse.persistence.queries.FetchGroup)12 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)8 EntityFetchGroup (org.eclipse.persistence.internal.queries.EntityFetchGroup)8 InvalidObject (org.eclipse.persistence.internal.helper.InvalidObject)6 ByteArrayInputStream (java.io.ByteArrayInputStream)4 InputStream (java.io.InputStream)4 DynamicEntity (org.eclipse.persistence.dynamic.DynamicEntity)4 CacheKey (org.eclipse.persistence.internal.identitymaps.CacheKey)4 PersistenceResource (org.eclipse.persistence.jpa.rs.resources.unversioned.PersistenceResource)4 Test (org.junit.Test)4 FetchGroupTracker (org.eclipse.persistence.queries.FetchGroupTracker)3 ArrayList (java.util.ArrayList)2 Vector (java.util.Vector)2 DescriptorEvent (org.eclipse.persistence.descriptors.DescriptorEvent)2 XMLInverseReferenceMapping (org.eclipse.persistence.oxm.mappings.XMLInverseReferenceMapping)2 ObjectLevelReadQuery (org.eclipse.persistence.queries.ObjectLevelReadQuery)2 ReadAllQuery (org.eclipse.persistence.queries.ReadAllQuery)2 JAXBException (jakarta.xml.bind.JAXBException)1