Search in sources :

Example 11 with ForeignKeyMetaData

use of org.datanucleus.metadata.ForeignKeyMetaData in project datanucleus-api-jdo by datanucleus.

the class ValueMetadataImpl method getForeignKeyMetadata.

/* (non-Javadoc)
     * @see javax.jdo.metadata.ValueMetadata#getForeignKeyMetadata()
     */
public ForeignKeyMetadata getForeignKeyMetadata() {
    ForeignKeyMetaData internalFkmd = getInternal().getForeignKeyMetaData();
    if (internalFkmd == null) {
        return null;
    }
    ForeignKeyMetadataImpl fkmd = new ForeignKeyMetadataImpl(internalFkmd);
    fkmd.parent = this;
    return fkmd;
}
Also used : ForeignKeyMetaData(org.datanucleus.metadata.ForeignKeyMetaData)

Example 12 with ForeignKeyMetaData

use of org.datanucleus.metadata.ForeignKeyMetaData in project datanucleus-api-jdo by datanucleus.

the class ElementMetadataImpl method getForeignKeyMetadata.

/* (non-Javadoc)
     * @see javax.jdo.metadata.ElementMetadata#getForeignKeyMetadata()
     */
public ForeignKeyMetadata getForeignKeyMetadata() {
    ForeignKeyMetaData internalFkmd = getInternal().getForeignKeyMetaData();
    if (internalFkmd == null) {
        return null;
    }
    ForeignKeyMetadataImpl fkmd = new ForeignKeyMetadataImpl(internalFkmd);
    fkmd.parent = this;
    return fkmd;
}
Also used : ForeignKeyMetaData(org.datanucleus.metadata.ForeignKeyMetaData)

Example 13 with ForeignKeyMetaData

use of org.datanucleus.metadata.ForeignKeyMetaData in project datanucleus-rdbms by datanucleus.

the class ClassTable method getExpectedForeignKeys.

/**
 * Accessor for the expected foreign keys for this table.
 * @param clr The ClassLoaderResolver
 * @return The expected foreign keys.
 */
public List<ForeignKey> getExpectedForeignKeys(ClassLoaderResolver clr) {
    assertIsInitialized();
    // Auto mode allows us to decide which FKs are needed as well as using what is in the users MetaData.
    boolean autoMode = false;
    if (storeMgr.getStringProperty(RDBMSPropertyNames.PROPERTY_RDBMS_CONSTRAINT_CREATE_MODE).equals("DataNucleus")) {
        autoMode = true;
    }
    ArrayList<ForeignKey> foreignKeys = new ArrayList<>();
    // Check each field for FK requirements (user-defined, or required)
    // <field><foreign-key>...</foreign-key></field>
    Set memberNumbersSet = memberMappingsMap.keySet();
    Iterator iter = memberNumbersSet.iterator();
    while (iter.hasNext()) {
        AbstractMemberMetaData mmd = (AbstractMemberMetaData) iter.next();
        JavaTypeMapping memberMapping = memberMappingsMap.get(mmd);
        if (memberMapping instanceof EmbeddedPCMapping) {
            EmbeddedPCMapping embMapping = (EmbeddedPCMapping) memberMapping;
            addExpectedForeignKeysForEmbeddedPCField(foreignKeys, autoMode, clr, embMapping);
        } else {
            if (ClassUtils.isReferenceType(mmd.getType()) && memberMapping instanceof ReferenceMapping) {
                // Field is a reference type, so add a FK to the table of the PC for each PC implementation
                Collection fks = TableUtils.getForeignKeysForReferenceField(memberMapping, mmd, autoMode, storeMgr, clr);
                foreignKeys.addAll(fks);
            } else if (storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(mmd.getType(), clr) != null && memberMapping.getNumberOfDatastoreMappings() > 0 && memberMapping instanceof PersistableMapping) {
                // Field is for a PC class with the FK at this side, so add a FK to the table of this PC
                ForeignKey fk = TableUtils.getForeignKeyForPCField(memberMapping, mmd, autoMode, storeMgr, clr);
                if (fk != null) {
                    // Check for dups (can happen if we override a persistent property for 1-1/N-1 in a subclass)
                    boolean exists = false;
                    for (ForeignKey theFK : foreignKeys) {
                        if (theFK.isEqual(fk)) {
                            exists = true;
                            break;
                        }
                    }
                    if (!exists) {
                        foreignKeys.add(fk);
                    }
                }
            }
        }
    }
    // FK from id column(s) to id column(s) of superclass, as specified by
    // <inheritance><join><foreign-key ...></join></inheritance>
    ForeignKeyMetaData idFkmd = (cmd.getInheritanceMetaData().getJoinMetaData() != null) ? cmd.getInheritanceMetaData().getJoinMetaData().getForeignKeyMetaData() : null;
    if (supertable != null && (autoMode || (idFkmd != null && idFkmd.getDeleteAction() != ForeignKeyAction.NONE))) {
        ForeignKey fk = new ForeignKey(getIdMapping(), dba, supertable, false);
        if (idFkmd != null && idFkmd.getName() != null) {
            fk.setName(idFkmd.getName());
        }
        foreignKeys.add(0, fk);
    }
    // Add any user-required FKs for the class as a whole
    // <class><foreign-key>...</foreign-key></field>
    Iterator<AbstractClassMetaData> cmdIter = managedClassMetaData.iterator();
    while (cmdIter.hasNext()) {
        AbstractClassMetaData thisCmd = cmdIter.next();
        List<ForeignKeyMetaData> fkmds = thisCmd.getForeignKeyMetaData();
        if (fkmds != null) {
            for (ForeignKeyMetaData fkmd : fkmds) {
                ForeignKey fk = getForeignKeyForForeignKeyMetaData(fkmd);
                if (fk != null) {
                    foreignKeys.add(fk);
                }
            }
        }
    }
    Map externalFks = getExternalFkMappings();
    if (!externalFks.isEmpty()) {
        // 1-N FK relationships - FK to id column(s) of owner table where this is the element table and we have a FK
        Collection externalFkKeys = externalFks.entrySet();
        Iterator<Map.Entry<AbstractMemberMetaData, JavaTypeMapping>> externalFkKeysIter = externalFkKeys.iterator();
        while (externalFkKeysIter.hasNext()) {
            Map.Entry<AbstractMemberMetaData, JavaTypeMapping> entry = externalFkKeysIter.next();
            AbstractMemberMetaData fmd = entry.getKey();
            DatastoreClass referencedTable = storeMgr.getDatastoreClass(fmd.getAbstractClassMetaData().getFullClassName(), clr);
            if (referencedTable != null) {
                // Take <foreign-key> from either <field> or <element>
                ForeignKeyMetaData fkmd = fmd.getForeignKeyMetaData();
                if (fkmd == null && fmd.getElementMetaData() != null) {
                    fkmd = fmd.getElementMetaData().getForeignKeyMetaData();
                }
                if ((fkmd != null && fkmd.getDeleteAction() != ForeignKeyAction.NONE) || autoMode) {
                    // Either has been specified by user, or using autoMode, so add FK
                    JavaTypeMapping fkMapping = entry.getValue();
                    ForeignKey fk = new ForeignKey(fkMapping, dba, referencedTable, true);
                    // Does nothing when no FK MetaData
                    fk.setForMetaData(fkmd);
                    if (!foreignKeys.contains(fk)) {
                        // Only add when not already present (in the case of shared FKs there can be dups here)
                        foreignKeys.add(fk);
                    }
                }
            }
        }
    }
    return foreignKeys;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) EmbeddedPCMapping(org.datanucleus.store.rdbms.mapping.java.EmbeddedPCMapping) ArrayList(java.util.ArrayList) ForeignKey(org.datanucleus.store.rdbms.key.ForeignKey) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) PersistableMapping(org.datanucleus.store.rdbms.mapping.java.PersistableMapping) ReferenceMapping(org.datanucleus.store.rdbms.mapping.java.ReferenceMapping) Iterator(java.util.Iterator) Collection(java.util.Collection) ForeignKeyMetaData(org.datanucleus.metadata.ForeignKeyMetaData) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) Map(java.util.Map) HashMap(java.util.HashMap)

Example 14 with ForeignKeyMetaData

use of org.datanucleus.metadata.ForeignKeyMetaData in project datanucleus-rdbms by datanucleus.

the class MapTable method getExpectedForeignKeys.

/**
 * Accessor for the expected foreign keys for this table.
 * @param clr The ClassLoaderResolver
 * @return The expected foreign keys.
 */
public List getExpectedForeignKeys(ClassLoaderResolver clr) {
    assertIsInitialized();
    boolean autoMode = false;
    if (storeMgr.getStringProperty(RDBMSPropertyNames.PROPERTY_RDBMS_CONSTRAINT_CREATE_MODE).equals("DataNucleus")) {
        autoMode = true;
    }
    ArrayList foreignKeys = new ArrayList();
    try {
        // FK from join table to owner table
        DatastoreClass referencedTable = storeMgr.getDatastoreClass(ownerType, clr);
        if (referencedTable != null) {
            // Take <foreign-key> from <join>
            ForeignKeyMetaData fkmd = null;
            if (mmd.getJoinMetaData() != null) {
                fkmd = mmd.getJoinMetaData().getForeignKeyMetaData();
            }
            if (fkmd != null || autoMode) {
                ForeignKey fk = new ForeignKey(ownerMapping, dba, referencedTable, true);
                fk.setForMetaData(fkmd);
                foreignKeys.add(fk);
            }
        }
        if (!isSerialisedValuePC()) {
            if (isEmbeddedValuePC()) {
                // Add any FKs for the fields of the (embedded) value
                EmbeddedValuePCMapping embMapping = (EmbeddedValuePCMapping) valueMapping;
                for (int i = 0; i < embMapping.getNumberOfJavaTypeMappings(); i++) {
                    JavaTypeMapping embFieldMapping = embMapping.getJavaTypeMapping(i);
                    AbstractMemberMetaData embFmd = embFieldMapping.getMemberMetaData();
                    if (ClassUtils.isReferenceType(embFmd.getType()) && embFieldMapping instanceof ReferenceMapping) {
                        // Field is a reference type, so add a FK to the table of the PC for each PC implementation
                        Collection fks = TableUtils.getForeignKeysForReferenceField(embFieldMapping, embFmd, autoMode, storeMgr, clr);
                        foreignKeys.addAll(fks);
                    } else if (storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(embFmd.getType(), clr) != null && embFieldMapping.getNumberOfDatastoreMappings() > 0 && embFieldMapping instanceof PersistableMapping) {
                        // Field is for a PC class with the FK at this side, so add a FK to the table of this PC
                        ForeignKey fk = TableUtils.getForeignKeyForPCField(embFieldMapping, embFmd, autoMode, storeMgr, clr);
                        if (fk != null) {
                            foreignKeys.add(fk);
                        }
                    }
                }
            } else if (mmd.getMap().valueIsPersistent()) {
                // FK from join table to value table
                referencedTable = storeMgr.getDatastoreClass(mmd.getMap().getValueType(), clr);
                if (referencedTable != null) {
                    // Take <foreign-key> from <value>
                    ForeignKeyMetaData fkmd = null;
                    if (mmd.getValueMetaData() != null) {
                        fkmd = mmd.getValueMetaData().getForeignKeyMetaData();
                    }
                    if (fkmd != null || autoMode) {
                        ForeignKey fk = new ForeignKey(valueMapping, dba, referencedTable, true);
                        fk.setForMetaData(fkmd);
                        foreignKeys.add(fk);
                    }
                }
            }
        }
        if (!isSerialisedKeyPC()) {
            if (isEmbeddedKeyPC()) {
                // Add any FKs for the fields of the (embedded) key
                EmbeddedKeyPCMapping embMapping = (EmbeddedKeyPCMapping) keyMapping;
                for (int i = 0; i < embMapping.getNumberOfJavaTypeMappings(); i++) {
                    JavaTypeMapping embFieldMapping = embMapping.getJavaTypeMapping(i);
                    AbstractMemberMetaData embFmd = embFieldMapping.getMemberMetaData();
                    if (ClassUtils.isReferenceType(embFmd.getType()) && embFieldMapping instanceof ReferenceMapping) {
                        // Field is a reference type, so add a FK to the table of the PC for each PC implementation
                        Collection fks = TableUtils.getForeignKeysForReferenceField(embFieldMapping, embFmd, autoMode, storeMgr, clr);
                        foreignKeys.addAll(fks);
                    } else if (storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(embFmd.getType(), clr) != null && embFieldMapping.getNumberOfDatastoreMappings() > 0 && embFieldMapping instanceof PersistableMapping) {
                        // Field is for a PC class with the FK at this side, so add a FK to the table of this PC
                        ForeignKey fk = TableUtils.getForeignKeyForPCField(embFieldMapping, embFmd, autoMode, storeMgr, clr);
                        if (fk != null) {
                            foreignKeys.add(fk);
                        }
                    }
                }
            } else if (mmd.getMap().keyIsPersistent()) {
                // FK from join table to key table
                referencedTable = storeMgr.getDatastoreClass(mmd.getMap().getKeyType(), clr);
                if (referencedTable != null) {
                    // Take <foreign-key> from <key>
                    ForeignKeyMetaData fkmd = null;
                    if (mmd.getKeyMetaData() != null) {
                        fkmd = mmd.getKeyMetaData().getForeignKeyMetaData();
                    }
                    if (fkmd != null || autoMode) {
                        ForeignKey fk = new ForeignKey(keyMapping, dba, referencedTable, true);
                        fk.setForMetaData(fkmd);
                        foreignKeys.add(fk);
                    }
                }
            }
        }
    } catch (NoTableManagedException e) {
    // expected when no table exists
    }
    return foreignKeys;
}
Also used : JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) ArrayList(java.util.ArrayList) EmbeddedValuePCMapping(org.datanucleus.store.rdbms.mapping.java.EmbeddedValuePCMapping) ForeignKey(org.datanucleus.store.rdbms.key.ForeignKey) PersistableMapping(org.datanucleus.store.rdbms.mapping.java.PersistableMapping) ReferenceMapping(org.datanucleus.store.rdbms.mapping.java.ReferenceMapping) Collection(java.util.Collection) ForeignKeyMetaData(org.datanucleus.metadata.ForeignKeyMetaData) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) NoTableManagedException(org.datanucleus.store.rdbms.exceptions.NoTableManagedException) EmbeddedKeyPCMapping(org.datanucleus.store.rdbms.mapping.java.EmbeddedKeyPCMapping)

Example 15 with ForeignKeyMetaData

use of org.datanucleus.metadata.ForeignKeyMetaData in project datanucleus-rdbms by datanucleus.

the class PersistableJoinTable method getExpectedForeignKeys.

/**
 * Accessor for the expected foreign keys for this table.
 * @param clr The ClassLoaderResolver
 * @return The expected foreign keys.
 */
public List getExpectedForeignKeys(ClassLoaderResolver clr) {
    assertIsInitialized();
    // Find the mode that we're operating in for FK addition
    boolean autoMode = false;
    if (storeMgr.getStringProperty(RDBMSPropertyNames.PROPERTY_RDBMS_CONSTRAINT_CREATE_MODE).equals("DataNucleus")) {
        autoMode = true;
    }
    ArrayList foreignKeys = new ArrayList();
    try {
        // FK from join table to owner table
        DatastoreClass referencedTable = storeMgr.getDatastoreClass(mmd.getClassName(true), clr);
        if (referencedTable != null) {
            // Single owner table, so add a single FK to the owner as appropriate
            // Take <foreign-key> from <join>
            ForeignKey fk = null;
            ForeignKeyMetaData fkmd = null;
            if (mmd.getJoinMetaData() != null) {
                fkmd = mmd.getJoinMetaData().getForeignKeyMetaData();
            }
            if (fkmd != null || autoMode) {
                fk = new ForeignKey(ownerMapping, dba, referencedTable, true);
                fk.setForMetaData(fkmd);
            }
            if (fk != null) {
                foreignKeys.add(fk);
            }
        }
        // FK from join table to related table
        referencedTable = storeMgr.getDatastoreClass(mmd.getTypeName(), clr);
        if (referencedTable != null) {
            // Take <foreign-key> from <field>
            ForeignKey fk = null;
            ForeignKeyMetaData fkmd = mmd.getForeignKeyMetaData();
            if (fkmd != null || autoMode) {
                fk = new ForeignKey(relatedMapping, dba, referencedTable, true);
                fk.setForMetaData(fkmd);
            }
            if (fk != null) {
                foreignKeys.add(fk);
            }
        }
    } catch (NoTableManagedException e) {
    // expected when no table exists
    }
    return foreignKeys;
}
Also used : ArrayList(java.util.ArrayList) ForeignKeyMetaData(org.datanucleus.metadata.ForeignKeyMetaData) ForeignKey(org.datanucleus.store.rdbms.key.ForeignKey) NoTableManagedException(org.datanucleus.store.rdbms.exceptions.NoTableManagedException)

Aggregations

ForeignKeyMetaData (org.datanucleus.metadata.ForeignKeyMetaData)26 ForeignKey (org.datanucleus.store.rdbms.key.ForeignKey)8 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)6 ArrayList (java.util.ArrayList)5 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)5 ColumnMetaData (org.datanucleus.metadata.ColumnMetaData)5 DiscriminatorMetaData (org.datanucleus.metadata.DiscriminatorMetaData)3 FetchGroupMetaData (org.datanucleus.metadata.FetchGroupMetaData)3 IndexMetaData (org.datanucleus.metadata.IndexMetaData)3 JoinMetaData (org.datanucleus.metadata.JoinMetaData)3 UniqueMetaData (org.datanucleus.metadata.UniqueMetaData)3 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)3 Collection (java.util.Collection)2 HashSet (java.util.HashSet)2 AttributeConverter (javax.jdo.AttributeConverter)2 Column (javax.jdo.annotations.Column)2 Extension (javax.jdo.annotations.Extension)2 ForeignKeyAction (javax.jdo.annotations.ForeignKeyAction)2 Persistent (javax.jdo.annotations.Persistent)2 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)2