Search in sources :

Example 1 with AggregateChangeRecord

use of org.eclipse.persistence.internal.sessions.AggregateChangeRecord in project eclipselink by eclipse-ee4j.

the class ObjectBuilder method getBaseChangeRecordForField.

/**
 * Return the base ChangeRecord for the given DatabaseField.
 * The object and all its relevant aggregates must exist.
 * The returned ChangeRecord is
 * either DirectToFieldChangeRecord or TransformationMappingChangeRecord,
 * or null.
 */
public ChangeRecord getBaseChangeRecordForField(ObjectChangeSet objectChangeSet, Object object, DatabaseField databaseField, AbstractSession session) {
    DatabaseMapping mapping = getMappingForField(databaseField);
    // Drill down through the mappings until we get the direct mapping to the databaseField.
    while (mapping.isAggregateObjectMapping()) {
        String attributeName = mapping.getAttributeName();
        Object aggregate = mapping.getAttributeValueFromObject(object);
        ClassDescriptor referenceDescriptor = mapping.getReferenceDescriptor();
        AggregateChangeRecord aggregateChangeRecord = (AggregateChangeRecord) objectChangeSet.getChangesForAttributeNamed(attributeName);
        if (aggregateChangeRecord == null) {
            aggregateChangeRecord = new AggregateChangeRecord(objectChangeSet);
            aggregateChangeRecord.setAttribute(attributeName);
            aggregateChangeRecord.setMapping(mapping);
            objectChangeSet.addChange(aggregateChangeRecord);
        }
        ObjectChangeSet aggregateChangeSet = (ObjectChangeSet) aggregateChangeRecord.getChangedObject();
        if (aggregateChangeSet == null) {
            aggregateChangeSet = referenceDescriptor.getObjectBuilder().createObjectChangeSet(aggregate, (UnitOfWorkChangeSet) objectChangeSet.getUOWChangeSet(), session);
            aggregateChangeRecord.setChangedObject(aggregateChangeSet);
        }
        mapping = referenceDescriptor.getObjectBuilder().getMappingForField(databaseField);
        objectChangeSet = aggregateChangeSet;
        object = aggregate;
    }
    String attributeName = mapping.getAttributeName();
    if (mapping.isAbstractDirectMapping()) {
        DirectToFieldChangeRecord changeRecord = (DirectToFieldChangeRecord) objectChangeSet.getChangesForAttributeNamed(attributeName);
        if (changeRecord == null) {
            changeRecord = new DirectToFieldChangeRecord(objectChangeSet);
            changeRecord.setAttribute(attributeName);
            changeRecord.setMapping(mapping);
            objectChangeSet.addChange(changeRecord);
        }
        return changeRecord;
    } else if (mapping.isTransformationMapping()) {
        TransformationMappingChangeRecord changeRecord = (TransformationMappingChangeRecord) objectChangeSet.getChangesForAttributeNamed(attributeName);
        if (changeRecord == null) {
            changeRecord = new TransformationMappingChangeRecord(objectChangeSet);
            changeRecord.setAttribute(attributeName);
            changeRecord.setMapping(mapping);
            objectChangeSet.addChange(changeRecord);
        }
        return changeRecord;
    } else {
        session.log(SessionLog.FINEST, SessionLog.QUERY, "field_for_unsupported_mapping_returned", databaseField, getDescriptor());
        return null;
    }
}
Also used : TransformationMappingChangeRecord(org.eclipse.persistence.internal.sessions.TransformationMappingChangeRecord) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) UnitOfWorkChangeSet(org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet) AggregateObjectChangeSet(org.eclipse.persistence.internal.sessions.AggregateObjectChangeSet) ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping) InvalidObject(org.eclipse.persistence.internal.helper.InvalidObject) AggregateChangeRecord(org.eclipse.persistence.internal.sessions.AggregateChangeRecord) DirectToFieldChangeRecord(org.eclipse.persistence.internal.sessions.DirectToFieldChangeRecord)

Example 2 with AggregateChangeRecord

use of org.eclipse.persistence.internal.sessions.AggregateChangeRecord in project eclipselink by eclipse-ee4j.

the class AggregateObjectMapping method readFromReturnRowIntoObject.

/**
 * INTERNAL:
 * Build an aggregate object from the specified return row and put it
 * in the specified target object.
 * Return row is merged into object after execution of insert or update call
 * according to ReturningPolicy.
 * If not null changeSet must correspond to targetObject. changeSet is updated with all of the field values in the row.
 */
public Object readFromReturnRowIntoObject(AbstractRecord row, Object targetObject, ReadObjectQuery query, Collection handledMappings, ObjectChangeSet changeSet) throws DatabaseException {
    Object aggregate = getAttributeValueFromObject(targetObject);
    ObjectChangeSet aggregateChangeSet = null;
    if (aggregate == null) {
        aggregate = readFromRowIntoObject(row, null, targetObject, null, query, query.getSession(), true);
    } else {
        if (changeSet != null && (!changeSet.isNew() || (query.getDescriptor() != null && query.getDescriptor().shouldUseFullChangeSetsForNewObjects()))) {
            aggregateChangeSet = getReferenceDescriptor(aggregate, query.getSession()).getObjectBuilder().createObjectChangeSet(aggregate, (UnitOfWorkChangeSet) ((UnitOfWorkImpl) query.getSession()).getUnitOfWorkChangeSet(), true, query.getSession());
        }
        AbstractRecord aggregateRow = new DatabaseRecord();
        int size = row.size();
        List<DatabaseField> fields = row.getFields();
        List values = row.getValues();
        List<DatabaseField> aggregateFields = getReferenceFields();
        for (int i = 0; i < size; i++) {
            DatabaseField field = fields.get(i);
            if (aggregateFields.contains(field)) {
                aggregateRow.add(field, values.get(i));
            }
        }
        getObjectBuilder(aggregate, query.getSession()).assignReturnRow(aggregate, query.getSession(), aggregateRow, aggregateChangeSet);
    }
    if (aggregate != null && isNullAllowed()) {
        boolean allAttributesNull = true;
        int nAggregateFields = this.fields.size();
        for (int i = 0; (i < nAggregateFields) && allAttributesNull; i++) {
            DatabaseField field = this.fields.elementAt(i);
            if (row.containsKey(field)) {
                allAttributesNull = row.get(field) == null;
            } else {
                Object fieldValue = valueFromObject(targetObject, field, query.getSession());
                if (fieldValue == null) {
                    Object baseValue = getDescriptor().getObjectBuilder().getBaseValueForField(field, targetObject);
                    if (baseValue != null) {
                        DatabaseMapping baseMapping = getDescriptor().getObjectBuilder().getBaseMappingForField(field);
                        if (baseMapping.isForeignReferenceMapping()) {
                            ForeignReferenceMapping refMapping = (ForeignReferenceMapping) baseMapping;
                            if (refMapping.usesIndirection()) {
                                allAttributesNull = refMapping.getIndirectionPolicy().objectIsInstantiated(baseValue);
                            }
                        } else if (baseMapping.isTransformationMapping()) {
                            AbstractTransformationMapping transMapping = (AbstractTransformationMapping) baseMapping;
                            if (transMapping.usesIndirection()) {
                                allAttributesNull = transMapping.getIndirectionPolicy().objectIsInstantiated(baseValue);
                            }
                        }
                    }
                } else {
                    allAttributesNull = false;
                }
            }
        }
        if (allAttributesNull) {
            aggregate = null;
            setAttributeValueInObject(targetObject, aggregate);
        }
    }
    if (changeSet != null && (!changeSet.isNew() || (query.getDescriptor() != null && query.getDescriptor().shouldUseFullChangeSetsForNewObjects()))) {
        AggregateChangeRecord record = (AggregateChangeRecord) changeSet.getChangesForAttributeNamed(getAttributeName());
        if (aggregate == null) {
            if (record != null) {
                record.setChangedObject(null);
            }
        } else {
            if (record == null) {
                record = new AggregateChangeRecord(changeSet);
                record.setAttribute(getAttributeName());
                record.setMapping(this);
                changeSet.addChange(record);
            }
            if (aggregateChangeSet == null) {
                // the old aggregate value was null
                aggregateChangeSet = getReferenceDescriptor(aggregate, query.getSession()).getObjectBuilder().createObjectChangeSet(aggregate, (UnitOfWorkChangeSet) ((UnitOfWorkImpl) query.getSession()).getUnitOfWorkChangeSet(), true, query.getSession());
            }
            record.setChangedObject(aggregateChangeSet);
        }
    }
    if (handledMappings != null) {
        handledMappings.add(this);
    }
    return aggregate;
}
Also used : DatabaseRecord(org.eclipse.persistence.sessions.DatabaseRecord) UnitOfWorkChangeSet(org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet) ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord) AbstractTransformationMapping(org.eclipse.persistence.mappings.foundation.AbstractTransformationMapping) DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField) List(java.util.List) ArrayList(java.util.ArrayList) AggregateChangeRecord(org.eclipse.persistence.internal.sessions.AggregateChangeRecord)

Aggregations

AggregateChangeRecord (org.eclipse.persistence.internal.sessions.AggregateChangeRecord)2 ObjectChangeSet (org.eclipse.persistence.internal.sessions.ObjectChangeSet)2 UnitOfWorkChangeSet (org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)1 DatabaseField (org.eclipse.persistence.internal.helper.DatabaseField)1 InvalidObject (org.eclipse.persistence.internal.helper.InvalidObject)1 AbstractRecord (org.eclipse.persistence.internal.sessions.AbstractRecord)1 AggregateObjectChangeSet (org.eclipse.persistence.internal.sessions.AggregateObjectChangeSet)1 DirectToFieldChangeRecord (org.eclipse.persistence.internal.sessions.DirectToFieldChangeRecord)1 TransformationMappingChangeRecord (org.eclipse.persistence.internal.sessions.TransformationMappingChangeRecord)1 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)1 AbstractTransformationMapping (org.eclipse.persistence.mappings.foundation.AbstractTransformationMapping)1 DatabaseRecord (org.eclipse.persistence.sessions.DatabaseRecord)1