Search in sources :

Example 1 with InterfaceMapping

use of org.datanucleus.store.rdbms.mapping.java.InterfaceMapping in project datanucleus-rdbms by datanucleus.

the class DynamicSchemaFieldManager method storeObjectField.

/**
 * Method to store an object field into the attached instance.
 * @param fieldNumber Number of the field to store
 * @param value the value in the detached instance
 */
public void storeObjectField(int fieldNumber, Object value) {
    if (value == null) {
        // No value so nothing to do
        return;
    }
    ExecutionContext ec = sm.getExecutionContext();
    ClassLoaderResolver clr = ec.getClassLoaderResolver();
    AbstractMemberMetaData mmd = sm.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
    if (mmd != null) {
        DatastoreClass table = rdbmsMgr.getDatastoreClass(sm.getObject().getClass().getName(), clr);
        JavaTypeMapping fieldMapping = table.getMemberMapping(mmd);
        if (fieldMapping != null) {
            if (fieldMapping instanceof InterfaceMapping) {
                // 1-1 Interface field
                InterfaceMapping intfMapping = (InterfaceMapping) fieldMapping;
                if (mmd.getFieldTypes() != null || mmd.hasExtension(MetaData.EXTENSION_MEMBER_IMPLEMENTATION_CLASSES)) {
                    // Field is defined to not accept this type so just return
                    return;
                }
                processInterfaceMappingForValue(intfMapping, value, mmd, ec);
            } else if (mmd.hasCollection() || mmd.hasArray()) {
                boolean hasJoin = false;
                if (mmd.getJoinMetaData() != null) {
                    hasJoin = true;
                } else {
                    AbstractMemberMetaData[] relMmds = mmd.getRelatedMemberMetaData(clr);
                    if (relMmds != null && relMmds[0].getJoinMetaData() != null) {
                        hasJoin = true;
                    }
                }
                if (!hasJoin) {
                    // Not join table so no supported schema updates
                    return;
                }
                Table joinTbl = fieldMapping.getStoreManager().getTable(mmd);
                ElementContainerTable collTbl = (ElementContainerTable) joinTbl;
                JavaTypeMapping elemMapping = collTbl.getElementMapping();
                if (elemMapping instanceof InterfaceMapping) {
                    InterfaceMapping intfMapping = (InterfaceMapping) elemMapping;
                    if (mmd.hasCollection()) {
                        Collection coll = (Collection) value;
                        if (coll.isEmpty()) {
                            return;
                        }
                        // Update value mapping using first element. Maybe we should do the same for all elements?
                        Object elementValue = coll.iterator().next();
                        processInterfaceMappingForValue(intfMapping, elementValue, mmd, ec);
                    } else if (mmd.hasArray()) {
                        if (Array.getLength(value) == 0) {
                            return;
                        }
                        // Update value mapping using first element. Maybe we should do the same for all elements?
                        Object elementValue = Array.get(value, 0);
                        processInterfaceMappingForValue(intfMapping, elementValue, mmd, ec);
                    }
                }
            } else if (mmd.hasMap()) {
                boolean hasJoin = false;
                if (mmd.getJoinMetaData() != null) {
                    hasJoin = true;
                } else {
                    AbstractMemberMetaData[] relMmds = mmd.getRelatedMemberMetaData(clr);
                    if (relMmds != null && relMmds[0].getJoinMetaData() != null) {
                        hasJoin = true;
                    }
                }
                if (!hasJoin) {
                    // Not join table so no supported schema updates
                    return;
                }
                Map map = (Map) value;
                if (map.isEmpty()) {
                    return;
                }
                Table joinTbl = fieldMapping.getStoreManager().getTable(mmd);
                MapTable mapTbl = (MapTable) joinTbl;
                JavaTypeMapping keyMapping = mapTbl.getKeyMapping();
                if (keyMapping instanceof InterfaceMapping) {
                    // Update key mapping using first key. Maybe we should do the same for all keys?
                    InterfaceMapping intfMapping = (InterfaceMapping) keyMapping;
                    Object keyValue = map.keySet().iterator().next();
                    processInterfaceMappingForValue(intfMapping, keyValue, mmd, ec);
                }
                JavaTypeMapping valMapping = mapTbl.getValueMapping();
                if (valMapping instanceof InterfaceMapping) {
                    // Update value mapping using first value. Maybe we should do the same for all values?
                    InterfaceMapping intfMapping = (InterfaceMapping) valMapping;
                    Object valValue = map.values().iterator().next();
                    processInterfaceMappingForValue(intfMapping, valValue, mmd, ec);
                }
            }
        }
    }
}
Also used : ElementContainerTable(org.datanucleus.store.rdbms.table.ElementContainerTable) Table(org.datanucleus.store.rdbms.table.Table) MapTable(org.datanucleus.store.rdbms.table.MapTable) InterfaceMapping(org.datanucleus.store.rdbms.mapping.java.InterfaceMapping) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) MapTable(org.datanucleus.store.rdbms.table.MapTable) ExecutionContext(org.datanucleus.ExecutionContext) Collection(java.util.Collection) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) Map(java.util.Map) ElementContainerTable(org.datanucleus.store.rdbms.table.ElementContainerTable)

Example 2 with InterfaceMapping

use of org.datanucleus.store.rdbms.mapping.java.InterfaceMapping in project datanucleus-rdbms by datanucleus.

the class ParameterSetter method storeObjectField.

public void storeObjectField(int fieldNumber, Object value) {
    StatementMappingIndex mapIdx = stmtMappings.getMappingForMemberPosition(fieldNumber);
    if (value == null && mapIdx.getMapping().getMemberMetaData().getNullValue() == NullValue.EXCEPTION) {
        throw new NucleusUserException(Localiser.msg("052400", mapIdx.getMapping().getMemberMetaData().getFullFieldName()));
    }
    try {
        JavaTypeMapping mapping = mapIdx.getMapping();
        boolean provideOwner = false;
        if (mapping instanceof EmbeddedPCMapping || mapping instanceof SerialisedPCMapping || mapping instanceof SerialisedReferenceMapping || mapping instanceof PersistableMapping || mapping instanceof InterfaceMapping) {
            // Pass in the owner StateManager/field for any mappings that have relations
            provideOwner = true;
        }
        if (mapIdx.getNumberOfParameterOccurrences() > 0) {
            for (int i = 0; i < mapIdx.getNumberOfParameterOccurrences(); i++) {
                // Set this value for all occurrences of this parameter
                if (provideOwner) {
                    mapping.setObject(ec, statement, mapIdx.getParameterPositionsForOccurrence(i), value, sm, fieldNumber);
                } else {
                    mapping.setObject(ec, statement, mapIdx.getParameterPositionsForOccurrence(i), value);
                }
            }
        } else {
            // Important : call setObject even if the paramIndices is null (reachability)
            if (provideOwner) {
                mapping.setObject(ec, statement, null, value, sm, fieldNumber);
            } else {
                mapping.setObject(ec, statement, null, value);
            }
        }
        AbstractMemberMetaData mmd = sm.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
        RelationType relationType = mmd.getRelationType(ec.getClassLoaderResolver());
        if (sm.getClassMetaData().getSCOMutableMemberFlags()[fieldNumber]) {
            SCOUtils.wrapSCOField(sm, fieldNumber, value, true);
        } else if (RelationType.isRelationSingleValued(relationType) && (mmd.getEmbeddedMetaData() != null && mmd.getEmbeddedMetaData().getOwnerMember() != null)) {
            // Embedded PC, so make sure the field is wrapped where appropriate TODO This should be part of ManagedRelationships
            sm.updateOwnerFieldInEmbeddedField(fieldNumber, value);
        }
    } catch (NotYetFlushedException e) {
        if (sm.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber).getNullValue() == NullValue.EXCEPTION) {
            throw e;
        }
        sm.updateFieldAfterInsert(e.getPersistable(), fieldNumber);
    }
}
Also used : InterfaceMapping(org.datanucleus.store.rdbms.mapping.java.InterfaceMapping) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) SerialisedReferenceMapping(org.datanucleus.store.rdbms.mapping.java.SerialisedReferenceMapping) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) EmbeddedPCMapping(org.datanucleus.store.rdbms.mapping.java.EmbeddedPCMapping) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) NotYetFlushedException(org.datanucleus.exceptions.NotYetFlushedException) PersistableMapping(org.datanucleus.store.rdbms.mapping.java.PersistableMapping) RelationType(org.datanucleus.metadata.RelationType) SerialisedPCMapping(org.datanucleus.store.rdbms.mapping.java.SerialisedPCMapping) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Aggregations

AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)2 InterfaceMapping (org.datanucleus.store.rdbms.mapping.java.InterfaceMapping)2 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)2 Collection (java.util.Collection)1 Map (java.util.Map)1 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)1 ExecutionContext (org.datanucleus.ExecutionContext)1 NotYetFlushedException (org.datanucleus.exceptions.NotYetFlushedException)1 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)1 RelationType (org.datanucleus.metadata.RelationType)1 EmbeddedPCMapping (org.datanucleus.store.rdbms.mapping.java.EmbeddedPCMapping)1 PersistableMapping (org.datanucleus.store.rdbms.mapping.java.PersistableMapping)1 SerialisedPCMapping (org.datanucleus.store.rdbms.mapping.java.SerialisedPCMapping)1 SerialisedReferenceMapping (org.datanucleus.store.rdbms.mapping.java.SerialisedReferenceMapping)1 StatementMappingIndex (org.datanucleus.store.rdbms.query.StatementMappingIndex)1 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)1 ElementContainerTable (org.datanucleus.store.rdbms.table.ElementContainerTable)1 MapTable (org.datanucleus.store.rdbms.table.MapTable)1 Table (org.datanucleus.store.rdbms.table.Table)1