Search in sources :

Example 1 with DirectToFieldChangeRecord

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

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

the class ObjectBuilder method assignReturnValueToMapping.

/**
 * INTERNAL:
 * Assign values from objectRow to the object through the mapping.
 * If not null changeSet must correspond to object. changeSet is updated with all of the field values in the row.
 */
protected void assignReturnValueToMapping(Object object, ReadObjectQuery query, AbstractRecord row, DatabaseField field, DatabaseMapping mapping, Collection handledMappings, ObjectChangeSet changeSet) {
    if ((handledMappings != null) && handledMappings.contains(mapping)) {
        return;
    }
    if (mapping.isAbstractDirectMapping()) {
        if (changeSet != null && (!changeSet.isNew() || (query.getDescriptor() != null && query.getDescriptor().shouldUseFullChangeSetsForNewObjects()))) {
            DirectToFieldChangeRecord changeRecord = (DirectToFieldChangeRecord) changeSet.getChangesForAttributeNamed(mapping.getAttributeName());
            Object oldAttributeValue = null;
            if (changeRecord == null) {
                oldAttributeValue = mapping.getAttributeValueFromObject(object);
            }
            // use null cachekey to ensure we build directly into the attribute
            Object attributeValue = mapping.readFromRowIntoObject(row, null, object, null, query, query.getSession(), true);
            if (changeRecord == null) {
                // Don't use ObjectChangeSet.updateChangeRecordForAttributeWithMappedObject to avoid unnecessary conversion - attributeValue is already converted.
                changeRecord = (DirectToFieldChangeRecord) ((AbstractDirectMapping) mapping).internalBuildChangeRecord(attributeValue, oldAttributeValue, changeSet);
                changeSet.addChange(changeRecord);
            } else {
                changeRecord.setNewValue(attributeValue);
            }
        } else {
            mapping.readFromRowIntoObject(row, null, object, null, query, query.getSession(), true);
        }
    } else if (mapping.isAggregateObjectMapping()) {
        ((AggregateObjectMapping) mapping).readFromReturnRowIntoObject(row, object, query, handledMappings, changeSet);
    } else if (mapping.isTransformationMapping()) {
        ((AbstractTransformationMapping) mapping).readFromReturnRowIntoObject(row, object, query, handledMappings, changeSet);
    } else {
        query.getSession().log(SessionLog.FINEST, SessionLog.QUERY, "field_for_unsupported_mapping_returned", field, this.descriptor);
    }
}
Also used : AbstractTransformationMapping(org.eclipse.persistence.mappings.foundation.AbstractTransformationMapping) AbstractDirectMapping(org.eclipse.persistence.mappings.foundation.AbstractDirectMapping) InvalidObject(org.eclipse.persistence.internal.helper.InvalidObject) DirectToFieldChangeRecord(org.eclipse.persistence.internal.sessions.DirectToFieldChangeRecord)

Example 3 with DirectToFieldChangeRecord

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

the class VersionLockingPolicy method updateObjectWithWriteValue.

public void updateObjectWithWriteValue(ObjectLevelModifyQuery query, Object lockValue) {
    AbstractSession session = query.getSession();
    Object object = query.getObject();
    ObjectChangeSet objectChangeSet = query.getObjectChangeSet();
    if (objectChangeSet == null) {
        if (session.isUnitOfWork() && (((UnitOfWorkImpl) session).getUnitOfWorkChangeSet() != null)) {
            // For aggregate collections the change set may be null, as they use the old commit still.
            objectChangeSet = (ObjectChangeSet) ((UnitOfWorkImpl) session).getUnitOfWorkChangeSet().getObjectChangeSetForClone(object);
        }
    }
    // PERF:  handle normal case faster.
    if (this.lockMapping != null) {
        // converted to the correct (for the mapping) type lock value.
        Object convertedLockValue = this.lockMapping.getObjectValue(lockValue, session);
        if (objectChangeSet != null && (!objectChangeSet.isNew() || query.getDescriptor().shouldUseFullChangeSetsForNewObjects())) {
            Object oldValue = this.lockMapping.getAttributeValueFromObject(object);
            this.lockMapping.setAttributeValueInObject(object, convertedLockValue);
            objectChangeSet.setWriteLockValue(lockValue);
            // Don't use ObjectChangeSet.updateChangeRecordForAttributeWithMappedObject to avoid unnecessary conversion - convertedLockValue is already converted.
            DirectToFieldChangeRecord changeRecord = new DirectToFieldChangeRecord(objectChangeSet);
            changeRecord.setAttribute(this.lockMapping.getAttributeName());
            changeRecord.setMapping(this.lockMapping);
            changeRecord.setNewValue(convertedLockValue);
            changeRecord.setOldValue(oldValue);
            objectChangeSet.addChange(changeRecord);
        } else {
            this.lockMapping.setAttributeValueInObject(object, convertedLockValue);
        }
    } else {
        // CR#3173211
        // If the value is stored in the cache or object, there still may
        // be read-only mappings for it, so the object must always be updated for
        // any writable or read-only mappings for the version value.
        // Reuse the method used for returning as has the same requirements.
        ObjectBuilder objectBuilder = this.descriptor.getObjectBuilder();
        AbstractRecord record = objectBuilder.createRecord(1, session);
        record.put(this.writeLockField, lockValue);
        if (objectChangeSet != null) {
            objectChangeSet.setWriteLockValue(lockValue);
        }
        objectBuilder.assignReturnRow(object, session, record, objectChangeSet);
    }
}
Also used : ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord) ObjectBuilder(org.eclipse.persistence.internal.descriptors.ObjectBuilder) DirectToFieldChangeRecord(org.eclipse.persistence.internal.sessions.DirectToFieldChangeRecord) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Example 4 with DirectToFieldChangeRecord

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

Aggregations

DirectToFieldChangeRecord (org.eclipse.persistence.internal.sessions.DirectToFieldChangeRecord)4 InvalidObject (org.eclipse.persistence.internal.helper.InvalidObject)3 ObjectChangeSet (org.eclipse.persistence.internal.sessions.ObjectChangeSet)3 AbstractRecord (org.eclipse.persistence.internal.sessions.AbstractRecord)2 AggregateChangeRecord (org.eclipse.persistence.internal.sessions.AggregateChangeRecord)2 AggregateObjectChangeSet (org.eclipse.persistence.internal.sessions.AggregateObjectChangeSet)2 TransformationMappingChangeRecord (org.eclipse.persistence.internal.sessions.TransformationMappingChangeRecord)2 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)2 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)1 ObjectBuilder (org.eclipse.persistence.internal.descriptors.ObjectBuilder)1 DatabaseField (org.eclipse.persistence.internal.helper.DatabaseField)1 AbstractSession (org.eclipse.persistence.internal.sessions.AbstractSession)1 ChangeRecord (org.eclipse.persistence.internal.sessions.ChangeRecord)1 UnitOfWorkChangeSet (org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet)1 AbstractDirectMapping (org.eclipse.persistence.mappings.foundation.AbstractDirectMapping)1 AbstractTransformationMapping (org.eclipse.persistence.mappings.foundation.AbstractTransformationMapping)1 ReadObjectQuery (org.eclipse.persistence.queries.ReadObjectQuery)1