Search in sources :

Example 11 with RelationType

use of org.datanucleus.metadata.RelationType in project datanucleus-core by datanucleus.

the class L2CacheRetrieveFieldManager method processElementContainer.

private Object processElementContainer(int fieldNumber, Object cachedContainer, AbstractMemberMetaData mmd, ContainerHandler<Object, ElementContainerAdapter<Object>> containerHandler) {
    try {
        // For arrays, rely on the metadata value
        Object newContainer = mmd.hasArray() ? containerHandler.newContainer(mmd) : newContainer(cachedContainer, mmd, containerHandler);
        ElementContainerAdapter<Object> fieldContainerAdapter = containerHandler.getAdapter(newContainer);
        RelationType relType = mmd.getRelationType(ec.getClassLoaderResolver());
        ElementContainerAdapter<Object> cachedContainerAdapter = containerHandler.getAdapter(cachedContainer);
        if (relType == RelationType.NONE) {
            String elementType = mmd.hasCollection() ? mmd.getCollection().getElementType() : mmd.getArray().getElementType();
            boolean mutableType = ec.getTypeManager().isSecondClassMutableType(elementType);
            if (mutableType) {
                // Container<mutable-SCO> - Create the container with a copy of the SCO mutable values
                for (Object mutableValue : cachedContainerAdapter) {
                    // TODO Need to return the value wrapped?
                    fieldContainerAdapter.add(SCOUtils.copyValue(mutableValue));
                }
            } else {
                // Container<immutable-SCO> - e.g. List<String> Create the container reusing the immutable object values
                for (Object value : cachedContainerAdapter) {
                    fieldContainerAdapter.add(value);
                }
            }
        } else {
            if ((containerHandler.isSerialised(mmd) || containerHandler.isEmbedded(mmd)) && ec.getNucleusContext().getConfiguration().getBooleanProperty(PropertyNames.PROPERTY_CACHE_L2_CACHE_EMBEDDED)) {
                // Collection/array of embedded elements (stored as nested CachedPC)
                for (Object cachedObject : cachedContainerAdapter) {
                    CachedPC elementCachedPC = (CachedPC) cachedObject;
                    Object element = null;
                    if (elementCachedPC != null) {
                        // Convert the CachedPC back into a managed object loading all cached fields
                        element = convertCachedPCToPersistable(elementCachedPC, mmd.getAbsoluteFieldNumber());
                    }
                    fieldContainerAdapter.add(element);
                }
            } else {
                // Collection/array of embedded elements (stored as "id")
                for (Object cachedId : cachedContainerAdapter) {
                    Object element = cachedId == null ? null : getObjectFromCachedId(cachedId);
                    fieldContainerAdapter.add(element);
                }
            }
        }
        return SCOUtils.wrapSCOField(op, fieldNumber, fieldContainerAdapter.getContainer(), true);
    } catch (Exception e) {
        // Error creating field value
        if (fieldsNotLoaded == null) {
            fieldsNotLoaded = new ArrayList<Integer>();
        }
        fieldsNotLoaded.add(fieldNumber);
        NucleusLogger.CACHE.error("Exception thrown creating value for field " + mmd.getFullFieldName() + " of type " + cachedContainer.getClass().getName(), e);
        return null;
    }
}
Also used : RelationType(org.datanucleus.metadata.RelationType) ArrayList(java.util.ArrayList) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException)

Example 12 with RelationType

use of org.datanucleus.metadata.RelationType in project datanucleus-core by datanucleus.

the class CompleteClassTable method processEmbeddedMember.

protected void processEmbeddedMember(List<AbstractMemberMetaData> mmds, ClassLoaderResolver clr, EmbeddedMetaData embmd, boolean ownerNested) {
    TypeManager typeMgr = storeMgr.getNucleusContext().getTypeManager();
    MetaDataManager mmgr = storeMgr.getMetaDataManager();
    NamingFactory namingFactory = storeMgr.getNamingFactory();
    AbstractMemberMetaData lastMmd = mmds.get(mmds.size() - 1);
    AbstractClassMetaData embCmd = null;
    if (lastMmd.hasCollection()) {
        // Embedded collection element
        embCmd = mmgr.getMetaDataForClass(lastMmd.getCollection().getElementType(), clr);
    } else if (lastMmd.hasArray()) {
        // Embedded array element
        embCmd = mmgr.getMetaDataForClass(lastMmd.getArray().getElementType(), clr);
    } else {
        // Embedded 1-1
        embCmd = mmgr.getMetaDataForClass(lastMmd.getType(), clr);
    }
    // Go through all members of the embedded class
    int[] memberPositions = embCmd.getAllMemberPositions();
    for (int i = 0; i < memberPositions.length; i++) {
        AbstractMemberMetaData mmd = embCmd.getMetaDataForManagedMemberAtAbsolutePosition(memberPositions[i]);
        if (mmd.getPersistenceModifier() != FieldPersistenceModifier.PERSISTENT) {
            // Don't need column if not persistent
            continue;
        }
        if (mmds.size() == 1 && embmd != null && embmd.getOwnerMember() != null && embmd.getOwnerMember().equals(mmd.getName())) {
            // Special case of this being a link back to the owner. TODO Repeat this for nested and their owners
            continue;
        }
        AbstractMemberMetaData embmdMmd = null;
        if (embmd != null) {
            AbstractMemberMetaData[] embmdMmds = embmd.getMemberMetaData();
            if (embmdMmds != null) {
                for (AbstractMemberMetaData thisMmd : embmdMmds) {
                    if (thisMmd.getName().equals(mmd.getName())) {
                        embmdMmd = thisMmd;
                        break;
                    }
                }
            }
        }
        RelationType relationType = mmd.getRelationType(clr);
        if (relationType != RelationType.NONE && MetaDataUtils.getInstance().isMemberEmbedded(mmgr, clr, mmd, relationType, lastMmd)) {
            if (RelationType.isRelationSingleValued(relationType)) {
                // Nested embedded PC, so recurse
                boolean nested = false;
                if (storeMgr.getSupportedOptions().contains(StoreManager.OPTION_ORM_EMBEDDED_PC_NESTED)) {
                    nested = !storeMgr.getNucleusContext().getConfiguration().getBooleanProperty(PropertyNames.PROPERTY_METADATA_EMBEDDED_PC_FLAT);
                    String nestedStr = mmd.getValueForExtension("nested");
                    if (nestedStr != null && nestedStr.equalsIgnoreCase("" + !nested)) {
                        nested = !nested;
                    }
                }
                List<AbstractMemberMetaData> embMmds = new ArrayList<AbstractMemberMetaData>(mmds);
                embMmds.add(mmd);
                if (nested) {
                    // Embedded object stored as nested under this in the owner table (where the datastore supports that)
                    // Add column for the owner of the embedded object, typically for the column name only
                    ColumnMetaData[] colmds = mmd.getColumnMetaData();
                    String colName = namingFactory.getColumnName(embMmds, 0);
                    ColumnImpl col = addEmbeddedColumn(colName, null);
                    col.setNested(true);
                    if (embmdMmd != null && embmdMmd.getColumnMetaData() != null && embmdMmd.getColumnMetaData().length == 1 && embmdMmd.getColumnMetaData()[0].getPosition() != null) {
                        col.setPosition(embmdMmd.getColumnMetaData()[0].getPosition());
                    } else if (colmds != null && colmds.length == 1 && colmds[0].getPosition() != null) {
                        col.setPosition(colmds[0].getPosition());
                    }
                    if (embmdMmd != null && embmdMmd.getColumnMetaData() != null && embmdMmd.getColumnMetaData().length == 1 && embmdMmd.getColumnMetaData()[0].getJdbcType() != null) {
                        col.setJdbcType(embmdMmd.getColumnMetaData()[0].getJdbcType());
                    } else if (colmds != null && colmds.length == 1 && colmds[0].getJdbcType() != null) {
                        col.setJdbcType(colmds[0].getJdbcType());
                    }
                    MemberColumnMapping mapping = new MemberColumnMappingImpl(mmd, col);
                    col.setMemberColumnMapping(mapping);
                    if (schemaVerifier != null) {
                        schemaVerifier.attributeEmbeddedMember(mapping, embMmds);
                    }
                    mappingByEmbeddedMember.put(getEmbeddedMemberNavigatedPath(embMmds), mapping);
                    // TODO Create mapping for the related info under the above column
                    processEmbeddedMember(embMmds, clr, embmdMmd != null ? embmdMmd.getEmbeddedMetaData() : null, true);
                } else {
                    // Embedded object stored flat into this table, with columns at same level as owner columns
                    processEmbeddedMember(embMmds, clr, embmdMmd != null ? embmdMmd.getEmbeddedMetaData() : null, false);
                }
            } else {
                if (mmd.hasCollection()) {
                    if (storeMgr.getSupportedOptions().contains(StoreManager.OPTION_ORM_EMBEDDED_COLLECTION_NESTED)) {
                    // TODO Support nested embedded collection element
                    }
                    NucleusLogger.DATASTORE_SCHEMA.warn("Member " + mmd.getFullFieldName() + " is an embedded collection. Not yet supported. Ignoring");
                    continue;
                } else if (mmd.hasMap()) {
                    if (storeMgr.getSupportedOptions().contains(StoreManager.OPTION_ORM_EMBEDDED_MAP_NESTED)) {
                    // TODO Support nested embedded map key/value
                    }
                    NucleusLogger.DATASTORE_SCHEMA.warn("Member " + mmd.getFullFieldName() + " is an embedded collection. Not yet supported. Ignoring");
                    continue;
                } else if (mmd.hasArray()) {
                    if (storeMgr.getSupportedOptions().contains(StoreManager.OPTION_ORM_EMBEDDED_ARRAY_NESTED)) {
                    // TODO Support nested embedded array element
                    }
                    NucleusLogger.DATASTORE_SCHEMA.warn("Member " + mmd.getFullFieldName() + " is an embedded array. Not yet supported. Ignoring");
                    continue;
                }
            }
        } else {
            List<AbstractMemberMetaData> embMmds = new ArrayList<AbstractMemberMetaData>(mmds);
            embMmds.add(mmd);
            ColumnMetaData[] colmds = mmd.getColumnMetaData();
            if (relationType != RelationType.NONE) {
                // 1-1/N-1 stored as single column with persistable-id
                // 1-N/M-N stored as single column with collection<persistable-id>
                // Create column for basic type
                String colName = namingFactory.getColumnName(embMmds, 0);
                ColumnImpl col = addEmbeddedColumn(colName, null);
                col.setNested(ownerNested);
                if (embmdMmd != null && embmdMmd.getColumnMetaData() != null && embmdMmd.getColumnMetaData().length == 1 && embmdMmd.getColumnMetaData()[0].getPosition() != null) {
                    col.setPosition(embmdMmd.getColumnMetaData()[0].getPosition());
                } else if (colmds != null && colmds.length == 1 && colmds[0].getPosition() != null) {
                    col.setPosition(colmds[0].getPosition());
                }
                if (embmdMmd != null && embmdMmd.getColumnMetaData() != null && embmdMmd.getColumnMetaData().length == 1 && embmdMmd.getColumnMetaData()[0].getJdbcType() != null) {
                    col.setJdbcType(embmdMmd.getColumnMetaData()[0].getJdbcType());
                } else if (colmds != null && colmds.length == 1 && colmds[0].getJdbcType() != null) {
                    col.setJdbcType(colmds[0].getJdbcType());
                }
                MemberColumnMapping mapping = new MemberColumnMappingImpl(mmd, col);
                col.setMemberColumnMapping(mapping);
                if (schemaVerifier != null) {
                    schemaVerifier.attributeEmbeddedMember(mapping, embMmds);
                }
                mappingByEmbeddedMember.put(getEmbeddedMemberNavigatedPath(embMmds), mapping);
            } else {
                // TODO Pass in embedded colmds if they have jdbcType info?
                TypeConverter typeConv = getTypeConverterForMember(mmd, colmds, typeMgr);
                if (typeConv != null) {
                    // Create column(s) for this TypeConverter
                    if (typeConv instanceof MultiColumnConverter) {
                        Class[] colJavaTypes = ((MultiColumnConverter) typeConv).getDatastoreColumnTypes();
                        Column[] cols = new Column[colJavaTypes.length];
                        for (int j = 0; j < colJavaTypes.length; j++) {
                            String colName = namingFactory.getColumnName(embMmds, j);
                            ColumnImpl col = addEmbeddedColumn(colName, typeConv);
                            col.setNested(ownerNested);
                            if (embmdMmd != null && embmdMmd.getColumnMetaData() != null && embmdMmd.getColumnMetaData().length == colJavaTypes.length && embmdMmd.getColumnMetaData()[j].getPosition() != null) {
                                col.setPosition(embmdMmd.getColumnMetaData()[j].getPosition());
                            } else if (colmds != null && colmds.length == colJavaTypes.length && colmds[j].getPosition() != null) {
                                col.setPosition(colmds[j].getPosition());
                            }
                            if (embmdMmd != null && embmdMmd.getColumnMetaData() != null && embmdMmd.getColumnMetaData().length == colJavaTypes.length && embmdMmd.getColumnMetaData()[j].getJdbcType() != null) {
                                col.setJdbcType(embmdMmd.getColumnMetaData()[j].getJdbcType());
                            } else if (colmds != null && colmds.length == colJavaTypes.length && colmds[j].getJdbcType() != null) {
                                col.setJdbcType(colmds[j].getJdbcType());
                            }
                            cols[j] = col;
                        }
                        MemberColumnMapping mapping = new MemberColumnMappingImpl(mmd, cols, typeConv);
                        for (int j = 0; j < colJavaTypes.length; j++) {
                            ((ColumnImpl) cols[j]).setMemberColumnMapping(mapping);
                        }
                        if (schemaVerifier != null) {
                            schemaVerifier.attributeEmbeddedMember(mapping, embMmds);
                        }
                        mappingByEmbeddedMember.put(getEmbeddedMemberNavigatedPath(embMmds), mapping);
                    } else {
                        String colName = namingFactory.getColumnName(embMmds, 0);
                        ColumnImpl col = addEmbeddedColumn(colName, typeConv);
                        col.setNested(ownerNested);
                        if (embmdMmd != null && embmdMmd.getColumnMetaData() != null && embmdMmd.getColumnMetaData().length == 1 && embmdMmd.getColumnMetaData()[0].getPosition() != null) {
                            col.setPosition(embmdMmd.getColumnMetaData()[0].getPosition());
                        } else if (colmds != null && colmds.length == 1 && colmds[0].getPosition() != null) {
                            col.setPosition(colmds[0].getPosition());
                        }
                        if (embmdMmd != null && embmdMmd.getColumnMetaData() != null && embmdMmd.getColumnMetaData().length == 1 && embmdMmd.getColumnMetaData()[0].getJdbcType() != null) {
                            col.setJdbcType(embmdMmd.getColumnMetaData()[0].getJdbcType());
                        } else if (colmds != null && colmds.length == 1 && colmds[0].getJdbcType() != null) {
                            col.setJdbcType(colmds[0].getJdbcType());
                        }
                        MemberColumnMapping mapping = new MemberColumnMappingImpl(mmd, col);
                        col.setMemberColumnMapping(mapping);
                        mapping.setTypeConverter(typeConv);
                        if (schemaVerifier != null) {
                            schemaVerifier.attributeEmbeddedMember(mapping, embMmds);
                        }
                        mappingByEmbeddedMember.put(getEmbeddedMemberNavigatedPath(embMmds), mapping);
                    }
                } else {
                    // Create column for basic type
                    String colName = namingFactory.getColumnName(embMmds, 0);
                    ColumnImpl col = addEmbeddedColumn(colName, null);
                    col.setNested(ownerNested);
                    AbstractMemberMetaData theMmd = embMmds.get(0);
                    if (theMmd.isPrimaryKey()) {
                        col.setPrimaryKey();
                    }
                    if (embmdMmd != null && embmdMmd.getColumnMetaData() != null && embmdMmd.getColumnMetaData().length == 1 && embmdMmd.getColumnMetaData()[0].getPosition() != null) {
                        col.setPosition(embmdMmd.getColumnMetaData()[0].getPosition());
                    } else if (colmds != null && colmds.length == 1 && colmds[0].getPosition() != null) {
                        col.setPosition(colmds[0].getPosition());
                    }
                    if (embmdMmd != null && embmdMmd.getColumnMetaData() != null && embmdMmd.getColumnMetaData().length == 1 && embmdMmd.getColumnMetaData()[0].getJdbcType() != null) {
                        col.setJdbcType(embmdMmd.getColumnMetaData()[0].getJdbcType());
                    } else if (colmds != null && colmds.length == 1 && colmds[0].getJdbcType() != null) {
                        col.setJdbcType(colmds[0].getJdbcType());
                    }
                    MemberColumnMapping mapping = new MemberColumnMappingImpl(mmd, col);
                    col.setMemberColumnMapping(mapping);
                    if (schemaVerifier != null) {
                        schemaVerifier.attributeEmbeddedMember(mapping, embMmds);
                    }
                    mappingByEmbeddedMember.put(getEmbeddedMemberNavigatedPath(embMmds), mapping);
                }
            }
        }
    }
}
Also used : ArrayList(java.util.ArrayList) MetaDataManager(org.datanucleus.metadata.MetaDataManager) MultiColumnConverter(org.datanucleus.store.types.converters.MultiColumnConverter) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) TypeConverter(org.datanucleus.store.types.converters.TypeConverter) RelationType(org.datanucleus.metadata.RelationType) TypeManager(org.datanucleus.store.types.TypeManager) ColumnMetaData(org.datanucleus.metadata.ColumnMetaData) NamingFactory(org.datanucleus.store.schema.naming.NamingFactory) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 13 with RelationType

use of org.datanucleus.metadata.RelationType in project datanucleus-core by datanucleus.

the class RelationshipManagerImpl method process.

/* (non-Javadoc)
     * @see org.datanucleus.state.RelationshipManager#process()
     */
public void process() {
    Iterator iter = fieldChanges.entrySet().iterator();
    while (iter.hasNext()) {
        Map.Entry<Integer, List<RelationChange>> entry = (Map.Entry) iter.next();
        int fieldNumber = entry.getKey().intValue();
        List<RelationChange> changes = entry.getValue();
        AbstractMemberMetaData mmd = ownerOP.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
        ClassLoaderResolver clr = ec.getClassLoaderResolver();
        RelationType relationType = mmd.getRelationType(clr);
        if (relationType == RelationType.ONE_TO_ONE_BI) {
            // 1-1 bidirectional
            processOneToOneBidirectionalRelation(mmd, clr, ec, changes);
        } else if (relationType == RelationType.MANY_TO_ONE_BI) {
            // N-1 bidirectional
            processManyToOneBidirectionalRelation(mmd, clr, ec, changes);
        } else if (relationType == RelationType.ONE_TO_MANY_BI) {
            // 1-N bidirectional
            processOneToManyBidirectionalRelation(mmd, clr, ec, changes);
        } else if (relationType == RelationType.MANY_TO_MANY_BI) {
            // M-N bidirectional
            processManyToManyBidirectionalRelation(mmd, clr, ec, changes);
        }
    }
}
Also used : RelationType(org.datanucleus.metadata.RelationType) Iterator(java.util.Iterator) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 14 with RelationType

use of org.datanucleus.metadata.RelationType in project datanucleus-core by datanucleus.

the class RelationshipManagerImpl method relationRemove.

/* (non-Javadoc)
     * @see org.datanucleus.state.RelationshipManager#relationRemove(int, java.lang.Object)
     */
public void relationRemove(int fieldNumber, Object val) {
    if (ec.isManagingRelations()) {
        return;
    }
    AbstractMemberMetaData mmd = ownerOP.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
    RelationType relationType = mmd.getRelationType(ec.getClassLoaderResolver());
    if (relationType != RelationType.ONE_TO_MANY_BI && relationType != RelationType.MANY_TO_MANY_BI) {
        return;
    }
    Integer fieldKey = Integer.valueOf(fieldNumber);
    List<RelationChange> changeList = fieldChanges.get(fieldKey);
    if (changeList == null) {
        changeList = new ArrayList();
        fieldChanges.put(fieldKey, changeList);
    }
    ec.removeObjectFromLevel2Cache(ec.getApiAdapter().getIdForObject(val));
    changeList.add(new RelationChange(ChangeType.REMOVE_OBJECT, val));
}
Also used : RelationType(org.datanucleus.metadata.RelationType) ArrayList(java.util.ArrayList) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 15 with RelationType

use of org.datanucleus.metadata.RelationType in project datanucleus-core by datanucleus.

the class RelationshipManagerImpl method checkConsistency.

/* (non-Javadoc)
     * @see org.datanucleus.state.RelationshipManager#checkConsistency()
     */
public void checkConsistency() {
    Iterator iter = fieldChanges.entrySet().iterator();
    while (iter.hasNext()) {
        Map.Entry<Integer, List<RelationChange>> entry = (Map.Entry) iter.next();
        int fieldNumber = entry.getKey().intValue();
        List<RelationChange> changes = entry.getValue();
        AbstractMemberMetaData mmd = ownerOP.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
        ClassLoaderResolver clr = ec.getClassLoaderResolver();
        RelationType relationType = mmd.getRelationType(clr);
        if (relationType == RelationType.ONE_TO_ONE_BI) {
            // 1-1 bidirectional
            checkOneToOneBidirectionalRelation(mmd, clr, ec, changes);
        } else if (relationType == RelationType.MANY_TO_ONE_BI) {
            // N-1 bidirectional
            checkManyToOneBidirectionalRelation(mmd, clr, ec, changes);
        } else if (relationType == RelationType.ONE_TO_MANY_BI) {
            // 1-N bidirectional
            checkOneToManyBidirectionalRelation(mmd, clr, ec, changes);
        } else if (relationType == RelationType.MANY_TO_MANY_BI) {
            // M-N bidirectional
            checkManyToManyBidirectionalRelation(mmd, clr, ec, changes);
        }
    }
}
Also used : RelationType(org.datanucleus.metadata.RelationType) Iterator(java.util.Iterator) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Aggregations

RelationType (org.datanucleus.metadata.RelationType)41 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)33 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)14 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)10 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)10 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)10 ArrayList (java.util.ArrayList)9 ExecutionContext (org.datanucleus.ExecutionContext)7 ApiAdapter (org.datanucleus.api.ApiAdapter)7 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)7 ObjectProvider (org.datanucleus.state.ObjectProvider)6 Collection (java.util.Collection)5 Iterator (java.util.Iterator)5 List (java.util.List)5 NucleusException (org.datanucleus.exceptions.NucleusException)5 HashMap (java.util.HashMap)4 HashSet (java.util.HashSet)4 Map (java.util.Map)4 ColumnMetaData (org.datanucleus.metadata.ColumnMetaData)4 EmbeddedPCMapping (org.datanucleus.store.rdbms.mapping.java.EmbeddedPCMapping)4