Search in sources :

Example 1 with FKMapStore

use of org.datanucleus.store.rdbms.scostore.FKMapStore in project datanucleus-rdbms by datanucleus.

the class RDBMSStoreManager method getBackingStoreForField.

/**
 * Accessor for the backing store for the specified member.
 * Note : if we have an embedded object that is embedded into some other type and the object has a member that requires a join table (backing store), this method
 * will not cater for the different places that can be embedded.
 * @param clr The ClassLoaderResolver
 * @param mmd metadata for the member to be persisted by this Store
 * @param type instantiated type or prefered type
 * @return The backing store
 */
public Store getBackingStoreForField(ClassLoaderResolver clr, AbstractMemberMetaData mmd, Class type) {
    if (mmd == null || mmd.isSerialized()) {
        return null;
    }
    Store store = backingStoreByMemberName.get(mmd.getFullFieldName());
    if (store != null) {
        return store;
    }
    synchronized (backingStoreByMemberName) {
        // Just in case we synced just after someone added since our previous lookup above
        store = backingStoreByMemberName.get(mmd.getFullFieldName());
        if (store != null) {
            return store;
        }
        Class expectedMappingType = null;
        if (mmd.getMap() != null) {
            expectedMappingType = MapMapping.class;
        } else if (mmd.getArray() != null) {
            expectedMappingType = ArrayMapping.class;
        } else if (mmd.getCollection() != null) {
            expectedMappingType = CollectionMapping.class;
        } else {
            expectedMappingType = PersistableMapping.class;
        }
        // Validate the mapping type matches the table
        try {
            DatastoreClass ownerTable = getDatastoreClass(mmd.getClassName(), clr);
            if (ownerTable == null) {
                // Class doesn't manage its own table (uses subclass-table, or superclass-table?)
                AbstractClassMetaData fieldTypeCmd = getMetaDataManager().getMetaDataForClass(mmd.getClassName(), clr);
                AbstractClassMetaData[] tableOwnerCmds = getClassesManagingTableForClass(fieldTypeCmd, clr);
                if (tableOwnerCmds != null && tableOwnerCmds.length == 1) {
                    ownerTable = getDatastoreClass(tableOwnerCmds[0].getFullClassName(), clr);
                }
            }
            if (ownerTable != null) {
                JavaTypeMapping m = ownerTable.getMemberMapping(mmd);
                if (!expectedMappingType.isAssignableFrom(m.getClass())) {
                    String requiredType = type != null ? type.getName() : mmd.getTypeName();
                    NucleusLogger.PERSISTENCE.warn("Member " + mmd.getFullFieldName() + " in table=" + ownerTable + " has mapping=" + m + " but expected mapping type=" + expectedMappingType);
                    throw new IncompatibleFieldTypeException(mmd.getFullFieldName(), requiredType, m.getType());
                }
            }
        } catch (NoTableManagedException ntme) {
        // Embedded, so just pass through
        }
        if (mmd.getMap() != null) {
            Table datastoreTable = getTable(mmd);
            if (datastoreTable == null) {
                store = new FKMapStore(mmd, this, clr);
            } else {
                store = new JoinMapStore((MapTable) datastoreTable, clr);
            }
        } else if (mmd.getArray() != null) {
            Table datastoreTable = getTable(mmd);
            if (datastoreTable != null) {
                store = new JoinArrayStore(mmd, (ArrayTable) datastoreTable, clr);
            } else {
                store = new FKArrayStore(mmd, this, clr);
            }
        } else if (mmd.getCollection() != null) {
            Table datastoreTable = getTable(mmd);
            if (type == null) {
                // No type to base it on so create it based on the field declared type
                if (datastoreTable == null) {
                    // We need a "FK" relation
                    if (Set.class.isAssignableFrom(mmd.getType())) {
                        store = new FKSetStore(mmd, this, clr);
                    } else if (List.class.isAssignableFrom(mmd.getType()) || Queue.class.isAssignableFrom(mmd.getType())) {
                        store = new FKListStore(mmd, this, clr);
                    } else if (mmd.getOrderMetaData() != null) {
                        // User has requested ordering
                        store = new FKListStore(mmd, this, clr);
                    } else {
                        store = new FKSetStore(mmd, this, clr);
                    }
                } else {
                    // We need a "JoinTable" relation.
                    if (Set.class.isAssignableFrom(mmd.getType())) {
                        store = new JoinSetStore(mmd, (CollectionTable) datastoreTable, clr);
                    } else if (List.class.isAssignableFrom(mmd.getType()) || Queue.class.isAssignableFrom(mmd.getType())) {
                        store = new JoinListStore(mmd, (CollectionTable) datastoreTable, clr);
                    } else if (mmd.getOrderMetaData() != null) {
                        // User has requested ordering
                        store = new JoinListStore(mmd, (CollectionTable) datastoreTable, clr);
                    } else {
                        store = new JoinSetStore(mmd, (CollectionTable) datastoreTable, clr);
                    }
                }
            } else {
                // Instantiated type specified, so use it to pick the associated backing store
                if (datastoreTable == null) {
                    if (SCOUtils.isListBased(type)) {
                        // List required
                        store = new FKListStore(mmd, this, clr);
                    } else {
                        // Set required
                        store = new FKSetStore(mmd, this, clr);
                    }
                } else {
                    if (SCOUtils.isListBased(type)) {
                        // List required
                        store = new JoinListStore(mmd, (CollectionTable) datastoreTable, clr);
                    } else {
                        // Set required
                        store = new JoinSetStore(mmd, (CollectionTable) datastoreTable, clr);
                    }
                }
            }
        } else {
            store = new JoinPersistableRelationStore(mmd, (PersistableJoinTable) getTable(mmd), clr);
        }
        backingStoreByMemberName.put(mmd.getFullFieldName(), store);
        return store;
    }
}
Also used : Table(org.datanucleus.store.rdbms.table.Table) ProbeTable(org.datanucleus.store.rdbms.table.ProbeTable) JoinTable(org.datanucleus.store.rdbms.table.JoinTable) ClassTable(org.datanucleus.store.rdbms.table.ClassTable) MapTable(org.datanucleus.store.rdbms.table.MapTable) PersistableJoinTable(org.datanucleus.store.rdbms.table.PersistableJoinTable) ArrayTable(org.datanucleus.store.rdbms.table.ArrayTable) CollectionTable(org.datanucleus.store.rdbms.table.CollectionTable) SequenceTable(org.datanucleus.store.rdbms.valuegenerator.SequenceTable) JoinArrayStore(org.datanucleus.store.rdbms.scostore.JoinArrayStore) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) JoinMapStore(org.datanucleus.store.rdbms.scostore.JoinMapStore) JoinSetStore(org.datanucleus.store.rdbms.scostore.JoinSetStore) JoinListStore(org.datanucleus.store.rdbms.scostore.JoinListStore) Store(org.datanucleus.store.types.scostore.Store) JoinArrayStore(org.datanucleus.store.rdbms.scostore.JoinArrayStore) JoinPersistableRelationStore(org.datanucleus.store.rdbms.scostore.JoinPersistableRelationStore) FKSetStore(org.datanucleus.store.rdbms.scostore.FKSetStore) FKListStore(org.datanucleus.store.rdbms.scostore.FKListStore) FKMapStore(org.datanucleus.store.rdbms.scostore.FKMapStore) FKArrayStore(org.datanucleus.store.rdbms.scostore.FKArrayStore) JoinMapStore(org.datanucleus.store.rdbms.scostore.JoinMapStore) IncompatibleFieldTypeException(org.datanucleus.store.types.IncompatibleFieldTypeException) MacroString(org.datanucleus.util.MacroString) JoinListStore(org.datanucleus.store.rdbms.scostore.JoinListStore) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) MapTable(org.datanucleus.store.rdbms.table.MapTable) ArrayMapping(org.datanucleus.store.rdbms.mapping.java.ArrayMapping) JoinSetStore(org.datanucleus.store.rdbms.scostore.JoinSetStore) CollectionTable(org.datanucleus.store.rdbms.table.CollectionTable) FKMapStore(org.datanucleus.store.rdbms.scostore.FKMapStore) FKSetStore(org.datanucleus.store.rdbms.scostore.FKSetStore) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) FKArrayStore(org.datanucleus.store.rdbms.scostore.FKArrayStore) PersistableJoinTable(org.datanucleus.store.rdbms.table.PersistableJoinTable) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) NoTableManagedException(org.datanucleus.store.rdbms.exceptions.NoTableManagedException) FKListStore(org.datanucleus.store.rdbms.scostore.FKListStore) JoinPersistableRelationStore(org.datanucleus.store.rdbms.scostore.JoinPersistableRelationStore)

Aggregations

AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)1 NoTableManagedException (org.datanucleus.store.rdbms.exceptions.NoTableManagedException)1 ArrayMapping (org.datanucleus.store.rdbms.mapping.java.ArrayMapping)1 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)1 FKArrayStore (org.datanucleus.store.rdbms.scostore.FKArrayStore)1 FKListStore (org.datanucleus.store.rdbms.scostore.FKListStore)1 FKMapStore (org.datanucleus.store.rdbms.scostore.FKMapStore)1 FKSetStore (org.datanucleus.store.rdbms.scostore.FKSetStore)1 JoinArrayStore (org.datanucleus.store.rdbms.scostore.JoinArrayStore)1 JoinListStore (org.datanucleus.store.rdbms.scostore.JoinListStore)1 JoinMapStore (org.datanucleus.store.rdbms.scostore.JoinMapStore)1 JoinPersistableRelationStore (org.datanucleus.store.rdbms.scostore.JoinPersistableRelationStore)1 JoinSetStore (org.datanucleus.store.rdbms.scostore.JoinSetStore)1 ArrayTable (org.datanucleus.store.rdbms.table.ArrayTable)1 ClassTable (org.datanucleus.store.rdbms.table.ClassTable)1 CollectionTable (org.datanucleus.store.rdbms.table.CollectionTable)1 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)1 JoinTable (org.datanucleus.store.rdbms.table.JoinTable)1 MapTable (org.datanucleus.store.rdbms.table.MapTable)1 PersistableJoinTable (org.datanucleus.store.rdbms.table.PersistableJoinTable)1