Search in sources :

Example 1 with TransformationMappingChangeRecord

use of org.eclipse.persistence.internal.sessions.TransformationMappingChangeRecord 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 TransformationMappingChangeRecord

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

the class AbstractTransformationMapping method internalBuildChangeRecord.

/**
 * INTERNAL:
 * Build a change record.
 */
public ChangeRecord internalBuildChangeRecord(Object clone, Object oldValue, ObjectChangeSet owner, AbstractSession session) {
    TransformationMappingChangeRecord changeRecord = new TransformationMappingChangeRecord(owner);
    changeRecord.setRow(buildPhantomRowFrom(clone, session));
    changeRecord.setAttribute(getAttributeName());
    changeRecord.setMapping(this);
    changeRecord.setOldValue(oldValue);
    return changeRecord;
}
Also used : TransformationMappingChangeRecord(org.eclipse.persistence.internal.sessions.TransformationMappingChangeRecord)

Example 3 with TransformationMappingChangeRecord

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

the class AbstractTransformationMapping method updateChangeRecord.

/**
 * INTERNAL:
 * Either create a new change record or update the change record with the new value.
 * This is used by attribute change tracking.
 */
@Override
public void updateChangeRecord(Object clone, Object newValue, Object oldValue, ObjectChangeSet objectChangeSet, UnitOfWorkImpl uow) {
    TransformationMappingChangeRecord changeRecord = (TransformationMappingChangeRecord) objectChangeSet.getChangesForAttributeNamed(this.getAttributeName());
    Object updatedObject = descriptor.getInstantiationPolicy().buildNewInstance();
    this.setAttributeValueInObject(updatedObject, newValue);
    if (!isWriteOnly()) {
        if (changeRecord == null) {
            objectChangeSet.addChange(internalBuildChangeRecord(updatedObject, oldValue, objectChangeSet, uow));
        } else {
            changeRecord.setRow(this.buildPhantomRowFrom(updatedObject, uow));
        }
    }
}
Also used : TransformationMappingChangeRecord(org.eclipse.persistence.internal.sessions.TransformationMappingChangeRecord)

Example 4 with TransformationMappingChangeRecord

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

the class ObjectBuilder method assignSequenceNumber.

/**
 * INTERNAL:
 * Update the object primary key by fetching a new sequence number from the accessor.
 * This assume the uses sequence numbers check has already been done.
 * Adds the assigned sequence value to writeQuery's modify row.
 * If object has a changeSet then sets sequence value into change set as an Id
 * adds it also to object's change set in a ChangeRecord if required.
 * @return the sequence value or null if not assigned.
 * @exception  DatabaseException - an error has occurred on the database.
 */
protected Object assignSequenceNumber(Object object, AbstractSession writeSession, WriteObjectQuery writeQuery) throws DatabaseException {
    DatabaseField sequenceNumberField = this.descriptor.getSequenceNumberField();
    Object existingValue = null;
    if (this.sequenceMapping != null) {
        existingValue = this.sequenceMapping.getAttributeValueFromObject(object);
    } else {
        existingValue = getBaseValueForField(sequenceNumberField, object);
    }
    // PERF: The (internal) support for letting the sequence decide this was removed,
    // as anything other than primitive should allow null and default as such.
    Object sequenceValue;
    int index = this.descriptor.getPrimaryKeyFields().indexOf(sequenceNumberField);
    if (isPrimaryKeyComponentInvalid(existingValue, index) || this.descriptor.getSequence().shouldAlwaysOverrideExistingValue()) {
        sequenceValue = writeSession.getSequencing().getNextValue(this.descriptor.getJavaClass());
    } else {
        return null;
    }
    // Check that the value is not null, this occurs on any databases using IDENTITY type sequencing.
    if (sequenceValue == null) {
        return null;
    }
    writeSession.log(SessionLog.FINEST, SessionLog.SEQUENCING, "assign_sequence", sequenceValue, object);
    Object convertedSequenceValue = null;
    if (this.sequenceMapping != null) {
        convertedSequenceValue = this.sequenceMapping.getObjectValue(sequenceValue, writeSession);
        this.sequenceMapping.setAttributeValueInObject(object, convertedSequenceValue);
    } else {
        // Now add the value to the object, this gets ugly.
        AbstractRecord tempRow = createRecord(1, writeSession);
        tempRow.put(sequenceNumberField, sequenceValue);
        // Require a query context to read into an object.
        ReadObjectQuery query = new ReadObjectQuery();
        query.setSession(writeSession);
        DatabaseMapping mapping = getBaseMappingForField(sequenceNumberField);
        Object sequenceIntoObject = getParentObjectForField(sequenceNumberField, object);
        // The following method will return the converted value for the sequence.
        convertedSequenceValue = mapping.readFromRowIntoObject(tempRow, null, sequenceIntoObject, null, query, writeSession, true);
    }
    // PERF: If PersistenceEntity is caching the primary key this must be cleared as the primary key has changed.
    clearPrimaryKey(object);
    if (writeQuery != null) {
        Object primaryKey = extractPrimaryKeyFromObject(object, writeSession);
        writeQuery.setPrimaryKey(primaryKey);
        AbstractRecord modifyRow = writeQuery.getModifyRow();
        // Update the row.
        modifyRow.put(sequenceNumberField, sequenceValue);
        if (descriptor.hasMultipleTables()) {
            addPrimaryKeyForNonDefaultTable(modifyRow, object, writeSession);
        }
        // Update the changeSet if there is one.
        if (writeSession.isUnitOfWork()) {
            ObjectChangeSet objectChangeSet = writeQuery.getObjectChangeSet();
            if ((objectChangeSet == null) && (((UnitOfWorkImpl) writeSession).getUnitOfWorkChangeSet() != null)) {
                objectChangeSet = (ObjectChangeSet) ((UnitOfWorkImpl) writeSession).getUnitOfWorkChangeSet().getObjectChangeSetForClone(object);
            }
            if (objectChangeSet != null) {
                // objectChangeSet.isNew() == true
                if (writeQuery.getDescriptor().shouldUseFullChangeSetsForNewObjects()) {
                    if (this.sequenceMapping != null) {
                        // Don't use ObjectChangeSet.updateChangeRecordForAttribute to avoid unnecessary conversion - convertedSequenceValue is already converted.
                        String attributeName = this.sequenceMapping.getAttributeName();
                        DirectToFieldChangeRecord changeRecord = (DirectToFieldChangeRecord) objectChangeSet.getChangesForAttributeNamed(attributeName);
                        if (changeRecord == null) {
                            changeRecord = new DirectToFieldChangeRecord(objectChangeSet);
                            changeRecord.setAttribute(attributeName);
                            changeRecord.setMapping(this.sequenceMapping);
                            objectChangeSet.addChange(changeRecord);
                        }
                        changeRecord.setNewValue(convertedSequenceValue);
                    } else {
                        ChangeRecord changeRecord = getBaseChangeRecordForField(objectChangeSet, object, sequenceNumberField, writeSession);
                        if (changeRecord.getMapping().isDirectCollectionMapping()) {
                            // assign converted value to the attribute
                            ((DirectToFieldChangeRecord) changeRecord).setNewValue(convertedSequenceValue);
                        } else if (changeRecord.getMapping().isTransformationMapping()) {
                            // put original (not converted) value into the record.
                            ((TransformationMappingChangeRecord) changeRecord).getRecord().put(sequenceNumberField, sequenceValue);
                        }
                    }
                }
                objectChangeSet.setId(primaryKey);
            }
        }
    }
    return convertedSequenceValue;
}
Also used : TransformationMappingChangeRecord(org.eclipse.persistence.internal.sessions.TransformationMappingChangeRecord) ReadObjectQuery(org.eclipse.persistence.queries.ReadObjectQuery) DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord) AggregateObjectChangeSet(org.eclipse.persistence.internal.sessions.AggregateObjectChangeSet) ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) InvalidObject(org.eclipse.persistence.internal.helper.InvalidObject) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping) TransformationMappingChangeRecord(org.eclipse.persistence.internal.sessions.TransformationMappingChangeRecord) AggregateChangeRecord(org.eclipse.persistence.internal.sessions.AggregateChangeRecord) ChangeRecord(org.eclipse.persistence.internal.sessions.ChangeRecord) DirectToFieldChangeRecord(org.eclipse.persistence.internal.sessions.DirectToFieldChangeRecord) DirectToFieldChangeRecord(org.eclipse.persistence.internal.sessions.DirectToFieldChangeRecord)

Example 5 with TransformationMappingChangeRecord

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

the class AbstractTransformationMapping method readFromReturnRowIntoObject.

/**
 * INTERNAL:
 * Extracts value from return row and set the attribute to the value in the object.
 * Return row is merged into object after execution of insert or update call
 * according to ReturningPolicy.
 */
public Object readFromReturnRowIntoObject(AbstractRecord row, Object object, ReadObjectQuery query, Collection handledMappings, ObjectChangeSet changeSet) throws DatabaseException {
    int size = this.fields.size();
    AbstractRecord transformationRow = new DatabaseRecord(size);
    for (int i = 0; i < size; i++) {
        DatabaseField field = this.fields.get(i);
        Object value;
        if (row.containsKey(field)) {
            value = row.get(field);
        } else {
            value = valueFromObject(object, field, query.getSession());
        }
        transformationRow.add(field, value);
    }
    if (changeSet != null && (!changeSet.isNew() || (query.getDescriptor() != null && query.getDescriptor().shouldUseFullChangeSetsForNewObjects()))) {
        TransformationMappingChangeRecord record = (TransformationMappingChangeRecord) changeSet.getChangesForAttributeNamed(attributeName);
        if (record == null) {
            record = new TransformationMappingChangeRecord(changeSet);
            record.setAttribute(attributeName);
            record.setMapping(this);
            record.setOldValue(getAttributeValueFromObject(object));
            changeSet.addChange(record);
        }
        record.setRow(transformationRow);
    }
    Object attributeValue = readFromRowIntoObject(transformationRow, null, object, null, query, query.getSession(), true);
    if (handledMappings != null) {
        handledMappings.add(this);
    }
    return attributeValue;
}
Also used : TransformationMappingChangeRecord(org.eclipse.persistence.internal.sessions.TransformationMappingChangeRecord) DatabaseRecord(org.eclipse.persistence.sessions.DatabaseRecord) DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord)

Aggregations

TransformationMappingChangeRecord (org.eclipse.persistence.internal.sessions.TransformationMappingChangeRecord)5 DatabaseField (org.eclipse.persistence.internal.helper.DatabaseField)2 InvalidObject (org.eclipse.persistence.internal.helper.InvalidObject)2 AbstractRecord (org.eclipse.persistence.internal.sessions.AbstractRecord)2 AggregateChangeRecord (org.eclipse.persistence.internal.sessions.AggregateChangeRecord)2 AggregateObjectChangeSet (org.eclipse.persistence.internal.sessions.AggregateObjectChangeSet)2 DirectToFieldChangeRecord (org.eclipse.persistence.internal.sessions.DirectToFieldChangeRecord)2 ObjectChangeSet (org.eclipse.persistence.internal.sessions.ObjectChangeSet)2 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)2 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)1 ChangeRecord (org.eclipse.persistence.internal.sessions.ChangeRecord)1 UnitOfWorkChangeSet (org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet)1 ReadObjectQuery (org.eclipse.persistence.queries.ReadObjectQuery)1 DatabaseRecord (org.eclipse.persistence.sessions.DatabaseRecord)1