Search in sources :

Example 1 with SCOMap

use of org.datanucleus.store.types.SCOMap in project datanucleus-core by datanucleus.

the class StateManagerImpl method replaceField.

/**
 * Method to change the value of a field in the PC object.
 * Adds on handling for embedded fields to the superclass handler.
 * @param pc The PC object
 * @param fieldNumber Number of field
 * @param value The new value of the field
 * @param makeDirty Whether to make the field dirty while replacing its value (in embedded owners)
 */
protected void replaceField(Persistable pc, int fieldNumber, Object value, boolean makeDirty) {
    List<EmbeddedOwnerRelation> embeddedOwners = myEC.getOwnerInformationForEmbedded(this);
    if (embeddedOwners != null) {
        // We do this before we actually change the object so we can compare with the old value
        for (EmbeddedOwnerRelation ownerRel : embeddedOwners) {
            StateManagerImpl ownerOP = (StateManagerImpl) ownerRel.getOwnerOP();
            AbstractMemberMetaData ownerMmd = ownerOP.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(ownerRel.getOwnerFieldNum());
            if (ownerMmd.getCollection() != null) {
                // PC Object embedded in collection
                Object ownerField = ownerOP.provideField(ownerRel.getOwnerFieldNum());
                if (ownerField instanceof SCOCollection) {
                    ((SCOCollection) ownerField).updateEmbeddedElement(myPC, fieldNumber, value, makeDirty);
                }
                if ((ownerOP.flags & FLAG_UPDATING_EMBEDDING_FIELDS_WITH_OWNER) == 0) {
                    // Update the owner when one of our fields have changed, EXCEPT when they have just notified us of our owner field!
                    if (makeDirty) {
                        ownerOP.makeDirty(ownerRel.getOwnerFieldNum());
                    }
                }
            } else if (ownerMmd.getMap() != null) {
                // PC Object embedded in map
                Object ownerField = ownerOP.provideField(ownerRel.getOwnerFieldNum());
                if (ownerField instanceof SCOMap) {
                    if (objectType == ObjectProvider.EMBEDDED_MAP_KEY_PC) {
                        ((SCOMap) ownerField).updateEmbeddedKey(myPC, fieldNumber, value, makeDirty);
                    }
                    if (objectType == ObjectProvider.EMBEDDED_MAP_VALUE_PC) {
                        ((SCOMap) ownerField).updateEmbeddedValue(myPC, fieldNumber, value, makeDirty);
                    }
                }
                if ((ownerOP.flags & FLAG_UPDATING_EMBEDDING_FIELDS_WITH_OWNER) == 0) {
                    // Update the owner when one of our fields have changed, EXCEPT when they have just notified us of our owner field!
                    if (makeDirty) {
                        ownerOP.makeDirty(ownerRel.getOwnerFieldNum());
                    }
                }
            } else {
                // PC Object embedded in PC object
                if ((ownerOP.flags & FLAG_UPDATING_EMBEDDING_FIELDS_WITH_OWNER) == 0) {
                    // Update the owner when one of our fields have changed, EXCEPT when they have just notified us of our owner field!
                    if (makeDirty) {
                        ownerOP.replaceFieldMakeDirty(ownerRel.getOwnerFieldNum(), pc);
                    } else {
                        ownerOP.replaceField(ownerRel.getOwnerFieldNum(), pc);
                    }
                }
            }
        }
    }
    // TODO Why don't we mark as dirty if non-tx ? Maybe need P_NONTRANS_DIRTY
    if (embeddedOwners == null && makeDirty && !myLC.isDeleted() && myEC.getTransaction().isActive()) {
        // Mark dirty (if not being deleted)
        boolean wasDirty = preWriteField(fieldNumber);
        replaceField(pc, fieldNumber, value);
        postWriteField(wasDirty);
    } else {
        replaceField(pc, fieldNumber, value);
    }
}
Also used : EmbeddedOwnerRelation(org.datanucleus.ExecutionContext.EmbeddedOwnerRelation) SCOCollection(org.datanucleus.store.types.SCOCollection) SCOMap(org.datanucleus.store.types.SCOMap) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Aggregations

EmbeddedOwnerRelation (org.datanucleus.ExecutionContext.EmbeddedOwnerRelation)1 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)1 SCOCollection (org.datanucleus.store.types.SCOCollection)1 SCOMap (org.datanucleus.store.types.SCOMap)1