Search in sources :

Example 21 with ContainerPolicy

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

the class OneToManyMapping method preDelete.

/**
 * INTERNAL:
 * Delete the reference objects.
 */
@Override
public void preDelete(DeleteObjectQuery query) throws DatabaseException, OptimisticLockException {
    if (!shouldObjectModifyCascadeToParts(query)) {
        if (this.listOrderField != null) {
            updateTargetRowPreDeleteSource(query);
        }
        return;
    }
    AbstractSession session = query.getSession();
    // else delete everything in one shot.
    if (mustDeleteReferenceObjectsOneByOne()) {
        Object objects = getRealCollectionAttributeValueFromObject(query.getObject(), session);
        ContainerPolicy cp = getContainerPolicy();
        if (this.isCascadeOnDeleteSetOnDatabase && session.isUnitOfWork()) {
            for (Object iterator = cp.iteratorFor(objects); cp.hasNext(iterator); ) {
                Object wrappedObject = cp.nextEntry(iterator, session);
                Object object = cp.unwrapIteratorResult(wrappedObject);
                ((UnitOfWorkImpl) session).getCascadeDeleteObjects().add(object);
            }
        }
        int cascade = query.getCascadePolicy();
        for (Object iterator = cp.iteratorFor(objects); cp.hasNext(iterator); ) {
            Object wrappedObject = cp.nextEntry(iterator, session);
            Object object = cp.unwrapIteratorResult(wrappedObject);
            // PERF: Avoid query execution if already deleted.
            if (!session.getCommitManager().isCommitCompletedInPostOrIgnore(object) || this.containerPolicy.propagatesEventsToCollection()) {
                if (session.isUnitOfWork() && ((UnitOfWorkImpl) session).isObjectNew(object)) {
                    session.getCommitManager().markIgnoreCommit(object);
                } else {
                    DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
                    deleteQuery.setIsExecutionClone(true);
                    deleteQuery.setObject(object);
                    deleteQuery.setCascadePolicy(cascade);
                    session.executeQuery(deleteQuery);
                    this.containerPolicy.propogatePreDelete(deleteQuery, wrappedObject);
                }
            }
        }
        if (!session.isUnitOfWork()) {
            // This deletes any objects on the database, as the collection in memory may have been changed.
            // This is not required for unit of work, as the update would have already deleted these objects,
            // and the backup copy will include the same objects causing double deletes.
            deleteReferenceObjectsLeftOnDatabase(query);
        }
    } else {
        deleteAll(query, session);
    }
}
Also used : ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) DeleteObjectQuery(org.eclipse.persistence.queries.DeleteObjectQuery) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Example 22 with ContainerPolicy

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

the class DirectMapMapping method iterateOnElement.

/**
 * INTERNAL:
 * Iterate on the specified element.
 */
@Override
public void iterateOnElement(DescriptorIterator iterator, Object element) {
    super.iterateOnElement(iterator, element);
    ContainerPolicy cp = getContainerPolicy();
    for (Object iter = cp.iteratorFor(element); cp.hasNext(iter); ) {
        Object wrappedObject = cp.nextEntry(iter, iterator.getSession());
        cp.iterateOnMapKey(iterator, wrappedObject);
    }
}
Also used : ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) MappedKeyMapContainerPolicy(org.eclipse.persistence.internal.queries.MappedKeyMapContainerPolicy)

Example 23 with ContainerPolicy

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

the class DirectMapMapping method valueFromRowInternalWithJoin.

/**
 * INTERNAL:
 * Return the value of the field from the row or a value holder on the query to obtain the object.
 */
@Override
protected Object valueFromRowInternalWithJoin(AbstractRecord row, JoinedAttributeManager joinManager, ObjectBuildingQuery sourceQuery, CacheKey parentCacheKey, AbstractSession executionSession, boolean isTargetProtected) throws DatabaseException {
    ContainerPolicy policy = getContainerPolicy();
    Object value = policy.containerInstance();
    ObjectBuilder objectBuilder = getDescriptor().getObjectBuilder();
    // Extract the primary key of the source object, to filter only the joined rows for that object.
    Object sourceKey = objectBuilder.extractPrimaryKeyFromRow(row, executionSession);
    // If the query was using joining, all of the result rows by primary key will have been computed.
    List<AbstractRecord> rows = joinManager.getDataResultsByPrimaryKey().get(sourceKey);
    // this can occur with pagination where the last row may not be complete.
    if (rows == null) {
        return valueFromRowInternal(row, joinManager, sourceQuery, executionSession);
    }
    // A set of direct values must be maintained to avoid duplicates from multiple 1-m joins.
    Set directValues = new HashSet();
    Converter valueConverter = getValueConverter();
    // For each rows, extract the target row and build the target object and add to the collection.
    int size = rows.size();
    for (int index = 0; index < size; index++) {
        AbstractRecord sourceRow = rows.get(index);
        AbstractRecord targetRow = sourceRow;
        // The field for many objects may be in the row,
        // so build the subpartion of the row through the computed values in the query,
        // this also helps the field indexing match.
        targetRow = trimRowForJoin(targetRow, joinManager, executionSession);
        // Partial object queries must select the primary key of the source and related objects.
        // If the target joined rows in null (outerjoin) means an empty collection.
        Object directKey = this.containerPolicy.buildKeyFromJoinedRow(targetRow, joinManager, sourceQuery, parentCacheKey, executionSession, isTargetProtected);
        if (directKey == null) {
            // A null direct value means an empty collection returned as nulls from an outerjoin.
            return getIndirectionPolicy().valueFromRow(value);
        }
        // Only build/add the target object once, skip duplicates from multiple 1-m joins.
        if (!directValues.contains(directKey)) {
            directValues.add(directKey);
            Object directValue = targetRow.get(this.directField);
            // Allow for value conversion.
            if (valueConverter != null) {
                directValue = valueConverter.convertDataValueToObjectValue(directValue, executionSession);
            }
            policy.addInto(directKey, directValue, value, executionSession);
        }
    }
    return getIndirectionPolicy().valueFromRow(value);
}
Also used : ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) MappedKeyMapContainerPolicy(org.eclipse.persistence.internal.queries.MappedKeyMapContainerPolicy) ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) Set(java.util.Set) HashSet(java.util.HashSet) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord) Converter(org.eclipse.persistence.mappings.converters.Converter) TypeConversionConverter(org.eclipse.persistence.mappings.converters.TypeConversionConverter) SerializedObjectConverter(org.eclipse.persistence.mappings.converters.SerializedObjectConverter) ObjectTypeConverter(org.eclipse.persistence.mappings.converters.ObjectTypeConverter) ObjectBuilder(org.eclipse.persistence.internal.descriptors.ObjectBuilder) HashSet(java.util.HashSet)

Example 24 with ContainerPolicy

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

the class ParameterExpression method validateParameterValueAgainstMapping.

/**
 * INTERNAL
 * Validate the passed parameter against the local base mapping.
 * Throw a QueryException if the parameter is of an incorrect class for object comparison.
 * Added for Bug 245268
 */
protected void validateParameterValueAgainstMapping(Object value, boolean useBaseExpression) {
    Expression queryKey = null;
    if (useBaseExpression) {
        // used to support validating against the base expression in the case of nesting
        ParameterExpression baseExpression = (ParameterExpression) getBaseExpression();
        queryKey = baseExpression.getLocalBase();
    } else {
        // used where we need to simply validate against the local base expression
        queryKey = this.getLocalBase();
    }
    if ((value != null) && !(value instanceof Collection) && (queryKey != null) && queryKey.isObjectExpression()) {
        DatabaseMapping mapping = ((ObjectExpression) queryKey).getMapping();
        if (mapping != null) {
            if (mapping.isCollectionMapping() && queryKey.isMapEntryExpression() && !((MapEntryExpression) queryKey).shouldReturnMapEntry()) {
                // this is a map key expression, operate on the key
                ContainerPolicy cp = mapping.getContainerPolicy();
                Object keyType = cp.getKeyType();
                Class<?> keyTypeClass = keyType instanceof Class<?> ? (Class) keyType : ((ClassDescriptor) keyType).getJavaClass();
                if (!keyTypeClass.isInstance(value)) {
                    throw QueryException.incorrectClassForObjectComparison(baseExpression, value, mapping);
                }
            } else if (mapping.isDirectCollectionMapping()) {
            // Do not validate direct collection, as type may be convertable.
            } else if (mapping.isForeignReferenceMapping() && !mapping.getReferenceDescriptor().getJavaClass().isInstance(value)) {
                throw QueryException.incorrectClassForObjectComparison(baseExpression, value, mapping);
            }
        }
    }
}
Also used : ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) Expression(org.eclipse.persistence.expressions.Expression) Collection(java.util.Collection) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping)

Example 25 with ContainerPolicy

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

the class AggregateCollectionMapping 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() && (!isAttributeValueInstantiatedOrChanged(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() && shouldMergeCascadeParts(mergeManager) && usesIndirection()) {
        mergeRemoteValueHolder(target, source, mergeManager);
        return;
    }
    if (mergeManager.isForRefresh()) {
        if (!isAttributeValueInstantiatedOrChanged(target)) {
            // the refresh that attribute
            return;
        }
    } else if (!isAttributeValueInstantiatedOrChanged(source)) {
        // modified
        return;
    }
    ContainerPolicy containerPolicy = getContainerPolicy();
    Object valueOfSource = getRealCollectionAttributeValueFromObject(source, mergeManager.getSession());
    Object valueOfTarget = containerPolicy.containerInstance(containerPolicy.sizeFor(valueOfSource));
    for (Object sourceValuesIterator = containerPolicy.iteratorFor(valueOfSource); containerPolicy.hasNext(sourceValuesIterator); ) {
        Object wrappedSourceValue = containerPolicy.nextEntry(sourceValuesIterator, mergeManager.getSession());
        Object sourceValue = containerPolicy.unwrapIteratorResult(wrappedSourceValue);
        // For some odd reason support for having null in the collection was added. This does not make sense...
        Object originalValue = null;
        if (sourceValue != null) {
            // CR#2896 - TW
            originalValue = getReferenceDescriptor(sourceValue.getClass(), mergeManager.getSession()).getObjectBuilder().buildNewInstance();
            getReferenceDescriptor(sourceValue.getClass(), mergeManager.getSession()).getObjectBuilder().mergeIntoObject(originalValue, true, sourceValue, mergeManager, targetSession);
            containerPolicy.addInto(containerPolicy.keyFromIterator(sourceValuesIterator), originalValue, valueOfTarget, mergeManager.getSession());
        }
    }
    // Must re-set variable to allow for set method to re-morph changes if the collection is not being stored directly.
    setRealAttributeValueInObject(target, valueOfTarget);
}
Also used : ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) ValueHolder(org.eclipse.persistence.indirection.ValueHolder)

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