Search in sources :

Example 96 with ContainerPolicy

use of org.eclipse.persistence.internal.queries.ContainerPolicy in project eclipselink by eclipse-ee4j.

the class ObjectBuildingQuery method triggerJoinExpressions.

/**
 * INTERNAL:
 * Fetch/trigger indirection on the clone passed in, based on join expressions in the joinManager.
 */
private void triggerJoinExpressions(UnitOfWorkImpl unitOfWork, JoinedAttributeManager joinManager, Object clone, ClassDescriptor concreteDescriptor) {
    List<Expression> joinExpressions = joinManager.getJoinedAttributeExpressions();
    int size = joinExpressions.size();
    if ((size == 0) || (clone == null)) {
        return;
    }
    for (int index = 0; index < size; index++) {
        // since a's descriptor won't have a mapping for 'b'.
        // baseExpression will be first relationship expression after the ExpressionBuilder, and may include aggregate intermediaries
        QueryKeyExpression baseExpression = (QueryKeyExpression) joinManager.getJoinedAttributes().get(index);
        DatabaseMapping mapping = joinManager.getJoinedAttributeMappings().get(index);
        if (mapping != null) {
            Object attributeValue = joinManager.getValueFromObjectForExpression(unitOfWork, clone, baseExpression);
            if (attributeValue != null) {
                // recurse through the mapping if the expression's base isn't the base expressionBuilder
                QueryKeyExpression queryKeyExpression = (QueryKeyExpression) joinExpressions.get(index);
                if (baseExpression != queryKeyExpression) {
                    ObjectLevelReadQuery nestedQuery = null;
                    if (joinManager.getJoinedMappingQueryClones() == null) {
                        if (joinManager.getJoinedMappingQueries_() != null) {
                            nestedQuery = joinManager.getJoinedMappingQueries_().get(mapping);
                        }
                    } else {
                        nestedQuery = joinManager.getJoinedMappingQueryClones().get(mapping);
                    }
                    // use the nestedQuery to trigger joins remaining for this expression (base onward)
                    if ((nestedQuery != null) && (nestedQuery.getJoinedAttributeManager() != null)) {
                        if (!mapping.isCollectionMapping()) {
                            triggerJoinExpressions(unitOfWork, nestedQuery.getJoinedAttributeManager(), attributeValue, null);
                        } else {
                            ContainerPolicy cp = mapping.getContainerPolicy();
                            Object iterator = cp.iteratorFor(attributeValue);
                            while (cp.hasNext(iterator)) {
                                triggerJoinExpressions(unitOfWork, nestedQuery.getJoinedAttributeManager(), cp.next(iterator, unitOfWork), null);
                            }
                        }
                    }
                }
            }
        }
    }
}
Also used : ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) QueryKeyExpression(org.eclipse.persistence.internal.expressions.QueryKeyExpression) Expression(org.eclipse.persistence.expressions.Expression) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping) QueryKeyExpression(org.eclipse.persistence.internal.expressions.QueryKeyExpression)

Example 97 with ContainerPolicy

use of org.eclipse.persistence.internal.queries.ContainerPolicy in project eclipselink by eclipse-ee4j.

the class ObjectBuilder method buildObjectsInto.

/**
 * Return a container which contains the instances of the receivers javaClass.
 * Set the fields of the instance to the values stored in the database rows.
 */
public Object buildObjectsInto(ReadAllQuery query, List databaseRows, Object domainObjects) {
    if (databaseRows instanceof ThreadCursoredList) {
        return buildObjectsFromCursorInto(query, databaseRows, domainObjects);
    }
    int size = databaseRows.size();
    if (size > 0) {
        AbstractSession session = query.getSession();
        session.startOperationProfile(SessionProfiler.ObjectBuilding, query, SessionProfiler.ALL);
        try {
            InheritancePolicy inheritancePolicy = null;
            if (this.descriptor.hasInheritance()) {
                inheritancePolicy = this.descriptor.getInheritancePolicy();
            }
            boolean isUnitOfWork = session.isUnitOfWork();
            boolean shouldCacheQueryResults = query.shouldCacheQueryResults();
            boolean shouldUseWrapperPolicy = query.shouldUseWrapperPolicy();
            // PERF: Avoid lazy init of join manager if no joining.
            JoinedAttributeManager joinManager = null;
            if (query.hasJoining()) {
                joinManager = query.getJoinedAttributeManager();
            }
            if (this.descriptor.getCachePolicy().shouldPrefetchCacheKeys() && query.shouldMaintainCache() && !query.shouldRetrieveBypassCache()) {
                Object[] pkList = new Object[size];
                for (int i = 0; i < size; ++i) {
                    pkList[i] = extractPrimaryKeyFromRow((AbstractRecord) databaseRows.get(i), session);
                }
                query.setPrefetchedCacheKeys(session.getIdentityMapAccessorInstance().getAllCacheKeysFromIdentityMapWithEntityPK(pkList, descriptor));
            }
            ContainerPolicy policy = query.getContainerPolicy();
            if (policy.shouldAddAll()) {
                List domainObjectsIn = new ArrayList(size);
                List<AbstractRecord> databaseRowsIn = new ArrayList(size);
                for (int index = 0; index < size; index++) {
                    AbstractRecord databaseRow = (AbstractRecord) databaseRows.get(index);
                    // PERF: 1-m joining nulls out duplicate rows.
                    if (databaseRow != null) {
                        domainObjectsIn.add(buildObject(query, databaseRow, joinManager, session, this.descriptor, inheritancePolicy, isUnitOfWork, shouldCacheQueryResults, shouldUseWrapperPolicy));
                        databaseRowsIn.add(databaseRow);
                    }
                }
                policy.addAll(domainObjectsIn, domainObjects, session, databaseRowsIn, query, null, true);
            } else {
                boolean quickAdd = (domainObjects instanceof Collection) && !this.hasWrapperPolicy;
                for (int index = 0; index < size; index++) {
                    AbstractRecord databaseRow = (AbstractRecord) databaseRows.get(index);
                    // PERF: 1-m joining nulls out duplicate rows.
                    if (databaseRow != null) {
                        Object domainObject = buildObject(query, databaseRow, joinManager, session, this.descriptor, inheritancePolicy, isUnitOfWork, shouldCacheQueryResults, shouldUseWrapperPolicy);
                        if (quickAdd) {
                            ((Collection) domainObjects).add(domainObject);
                        } else {
                            policy.addInto(domainObject, domainObjects, session, databaseRow, query, null, true);
                        }
                    }
                }
            }
        } finally {
            session.endOperationProfile(SessionProfiler.ObjectBuilding, query, SessionProfiler.ALL);
        }
    }
    return domainObjects;
}
Also used : ThreadCursoredList(org.eclipse.persistence.internal.helper.ThreadCursoredList) JoinedAttributeManager(org.eclipse.persistence.internal.queries.JoinedAttributeManager) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord) ArrayList(java.util.ArrayList) ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) InheritancePolicy(org.eclipse.persistence.descriptors.InheritancePolicy) Collection(java.util.Collection) InvalidObject(org.eclipse.persistence.internal.helper.InvalidObject) ThreadCursoredList(org.eclipse.persistence.internal.helper.ThreadCursoredList) ArrayList(java.util.ArrayList) List(java.util.List) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Example 98 with ContainerPolicy

use of org.eclipse.persistence.internal.queries.ContainerPolicy in project eclipselink by eclipse-ee4j.

the class ObjectBuilder method buildObjectsFromResultSetInto.

/**
 * Version of buildObjectsInto method that takes call instead of rows.
 * Return a container which contains the instances of the receivers javaClass.
 * Set the fields of the instance to the values stored in the result set.
 */
public Object buildObjectsFromResultSetInto(ReadAllQuery query, ResultSet resultSet, Vector fields, DatabaseField[] fieldsArray, Object domainObjects) throws SQLException {
    AbstractSession session = query.getSession();
    session.startOperationProfile(SessionProfiler.ObjectBuilding, query, SessionProfiler.ALL);
    try {
        boolean hasNext = resultSet.next();
        if (hasNext) {
            InheritancePolicy inheritancePolicy = null;
            if (this.descriptor.hasInheritance()) {
                inheritancePolicy = this.descriptor.getInheritancePolicy();
            }
            boolean isUnitOfWork = session.isUnitOfWork();
            boolean shouldCacheQueryResults = query.shouldCacheQueryResults();
            boolean shouldUseWrapperPolicy = query.shouldUseWrapperPolicy();
            // PERF: Avoid lazy init of join manager if no joining.
            JoinedAttributeManager joinManager = null;
            if (query.hasJoining()) {
                joinManager = query.getJoinedAttributeManager();
            }
            ContainerPolicy policy = query.getContainerPolicy();
            // !cp.shouldAddAll() - query with SortedListContainerPolicy - currently does not use this method
            boolean quickAdd = (domainObjects instanceof Collection) && !this.hasWrapperPolicy;
            ResultSetMetaData metaData = resultSet.getMetaData();
            ResultSetRecord row = null;
            AbstractSession executionSession = query.getExecutionSession();
            DatabaseAccessor dbAccessor = (DatabaseAccessor) query.getAccessor();
            DatabasePlatform platform = dbAccessor.getPlatform();
            boolean optimizeData = platform.shouldOptimizeDataConversion();
            if (this.isSimple) {
                // None of the fields are relational - the row could be reused, just clear all the values.
                row = new SimpleResultSetRecord(fields, fieldsArray, resultSet, metaData, dbAccessor, executionSession, platform, optimizeData);
                if (this.descriptor.isDescriptorTypeAggregate()) {
                    // Aggregate Collection may have an unmapped primary key referencing the owner, the corresponding field will not be used when the object is populated and therefore may not be cleared.
                    ((SimpleResultSetRecord) row).setShouldKeepValues(true);
                }
            }
            while (hasNext) {
                if (!this.isSimple) {
                    row = new ResultSetRecord(fields, fieldsArray, resultSet, metaData, dbAccessor, executionSession, platform, optimizeData);
                }
                Object domainObject = buildObject(query, row, joinManager, session, this.descriptor, inheritancePolicy, isUnitOfWork, shouldCacheQueryResults, shouldUseWrapperPolicy);
                if (quickAdd) {
                    ((Collection) domainObjects).add(domainObject);
                } else {
                    // query with MappedKeyMapPolicy currently does not use this method
                    policy.addInto(domainObject, domainObjects, session);
                }
                if (this.isSimple) {
                    ((SimpleResultSetRecord) row).reset();
                } else {
                    if (this.shouldKeepRow) {
                        if (row.hasResultSet()) {
                            // ResultSet has not been fully triggered - that means the cached object was used.
                            // Yet the row still may be cached in a value holder (see loadBatchReadAttributes and loadJoinedAttributes methods).
                            // Remove ResultSet to avoid attempt to trigger it (already closed) when pk or fk values (already extracted) accessed when the value holder is instantiated.
                            row.removeResultSet();
                        } else {
                            row.removeNonIndirectionValues();
                        }
                    }
                }
                hasNext = resultSet.next();
            }
        }
    } finally {
        session.endOperationProfile(SessionProfiler.ObjectBuilding, query, SessionProfiler.ALL);
    }
    return domainObjects;
}
Also used : ResultSetMetaData(java.sql.ResultSetMetaData) ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) InheritancePolicy(org.eclipse.persistence.descriptors.InheritancePolicy) JoinedAttributeManager(org.eclipse.persistence.internal.queries.JoinedAttributeManager) Collection(java.util.Collection) SimpleResultSetRecord(org.eclipse.persistence.internal.sessions.SimpleResultSetRecord) ResultSetRecord(org.eclipse.persistence.internal.sessions.ResultSetRecord) DatabaseAccessor(org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor) InvalidObject(org.eclipse.persistence.internal.helper.InvalidObject) DatabasePlatform(org.eclipse.persistence.internal.databaseaccess.DatabasePlatform) SimpleResultSetRecord(org.eclipse.persistence.internal.sessions.SimpleResultSetRecord) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Example 99 with ContainerPolicy

use of org.eclipse.persistence.internal.queries.ContainerPolicy in project eclipselink by eclipse-ee4j.

the class TypeHelperImpl method resolveMapKey.

/**
 * Returns the type of the map key for the mapping on ownerClass named attribute
 * Returns null if that mapping does not exist or does not contain a map key
 */
@Override
public Object resolveMapKey(Object ownerClass, String attribute) {
    Object type = null;
    DatabaseMapping mapping = resolveAttributeMapping(ownerClass, attribute);
    if (mapping.isCollectionMapping()) {
        ContainerPolicy cp = mapping.getContainerPolicy();
        type = cp.getKeyType();
    }
    return type;
}
Also used : ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping)

Example 100 with ContainerPolicy

use of org.eclipse.persistence.internal.queries.ContainerPolicy in project eclipselink by eclipse-ee4j.

the class DirectCollectionMapping method compareCollectionsForChange.

/**
 * INTERNAL:
 * This method is used to calculate the differences between two collections.
 */
@Override
public void compareCollectionsForChange(Object oldCollection, Object newCollection, ChangeRecord changeRecord, AbstractSession session) {
    if (this.listOrderField != null) {
        compareListsForChange((List) oldCollection, (List) newCollection, changeRecord, session);
        return;
    }
    ContainerPolicy cp = getContainerPolicy();
    int numberOfNewNulls = 0;
    HashMap originalKeyValues = new HashMap(10);
    HashMap cloneKeyValues = new HashMap(10);
    if (oldCollection != null) {
        Object backUpIter = cp.iteratorFor(oldCollection);
        while (cp.hasNext(backUpIter)) {
            // Make a lookup of the objects
            Object secondObject = cp.next(backUpIter, session);
            // For CR#2258/CR#2378 handle null values inserted in a collection.
            if (secondObject == null) {
                numberOfNewNulls--;
            } else {
                Integer count = (Integer) originalKeyValues.get(secondObject);
                if (count == null) {
                    originalKeyValues.put(secondObject, 1);
                } else {
                    originalKeyValues.put(secondObject, count + 1);
                }
            }
        }
    }
    // should a removal occur this is the original count of objects on the database.
    // this value is used to determine how many objects to re-insert after the delete as a
    // delete will delete all of the objects not just one.
    HashMap databaseCount = (HashMap) originalKeyValues.clone();
    int databaseNullCount = Math.abs(numberOfNewNulls);
    if (newCollection != null) {
        Object cloneIter = cp.iteratorFor(newCollection);
        /* The following code is used to compare objects in a direct collection.
               Because objects in a direct collection are primitives and may be the same object
               the following code must count the number of instances in the collection not just the
               existence of an object.
            */
        while (cp.hasNext(cloneIter)) {
            // Compare them with the objects from the clone
            Object firstObject = cp.next(cloneIter, session);
            // For CR#2258/CR#2378 handle null values inserted in a collection.
            if (firstObject == null) {
                numberOfNewNulls++;
            } else {
                Integer count = (Integer) originalKeyValues.get(firstObject);
                if (count == null) {
                    // the object was not in the backup
                    Integer cloneCount = (Integer) cloneKeyValues.get(firstObject);
                    // Add it to the additions hashtable
                    if (cloneCount == null) {
                        cloneKeyValues.put(firstObject, 1);
                    } else {
                        cloneKeyValues.put(firstObject, cloneCount + 1);
                    }
                } else if (count == 1) {
                    // There is only one object so remove the whole reference
                    originalKeyValues.remove(firstObject);
                } else {
                    originalKeyValues.put(firstObject, count - 1);
                }
            }
        }
    }
    if (cloneKeyValues.isEmpty() && originalKeyValues.isEmpty() && (numberOfNewNulls == 0) && (!changeRecord.getOwner().isNew())) {
        return;
    }
    ((DirectCollectionChangeRecord) changeRecord).clearChanges();
    ((DirectCollectionChangeRecord) changeRecord).addAdditionChange(cloneKeyValues, databaseCount);
    ((DirectCollectionChangeRecord) changeRecord).addRemoveChange(originalKeyValues, databaseCount);
    ((DirectCollectionChangeRecord) changeRecord).setIsDeferred(false);
    ((DirectCollectionChangeRecord) changeRecord).setLatestCollection(null);
    // For CR#2258, produce a changeRecord which reflects the addition and removal of null values.
    if (numberOfNewNulls != 0) {
        ((DirectCollectionChangeRecord) changeRecord).getCommitAddMap().put(null, databaseNullCount);
        if (numberOfNewNulls > 0) {
            ((DirectCollectionChangeRecord) changeRecord).addAdditionChange(null, numberOfNewNulls);
        } else {
            numberOfNewNulls *= -1;
            ((DirectCollectionChangeRecord) changeRecord).addRemoveChange(null, numberOfNewNulls);
        }
    }
}
Also used : OrderedListContainerPolicy(org.eclipse.persistence.internal.queries.OrderedListContainerPolicy) ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) DirectCollectionChangeRecord(org.eclipse.persistence.internal.sessions.DirectCollectionChangeRecord)

Aggregations

ContainerPolicy (org.eclipse.persistence.internal.queries.ContainerPolicy)119 AbstractSession (org.eclipse.persistence.internal.sessions.AbstractSession)28 AbstractRecord (org.eclipse.persistence.internal.sessions.AbstractRecord)17 XMLRecord (org.eclipse.persistence.oxm.record.XMLRecord)17 List (java.util.List)14 Vector (java.util.Vector)14 DatabaseField (org.eclipse.persistence.internal.helper.DatabaseField)14 XMLField (org.eclipse.persistence.oxm.XMLField)14 ArrayList (java.util.ArrayList)13 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)13 Collection (java.util.Collection)12 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)10 CollectionContainerPolicy (org.eclipse.persistence.internal.queries.CollectionContainerPolicy)9 InstanceVariableAttributeAccessor (org.eclipse.persistence.internal.descriptors.InstanceVariableAttributeAccessor)8 MethodAttributeAccessor (org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor)8 AttributeAccessor (org.eclipse.persistence.mappings.AttributeAccessor)8 HashMap (java.util.HashMap)7 VirtualAttributeAccessor (org.eclipse.persistence.internal.descriptors.VirtualAttributeAccessor)7 CustomAccessorAttributeAccessor (org.eclipse.persistence.internal.jaxb.CustomAccessorAttributeAccessor)7 JAXBSetMethodAttributeAccessor (org.eclipse.persistence.internal.jaxb.JAXBSetMethodAttributeAccessor)7