Search in sources :

Example 31 with DatastoreClass

use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.

the class RDBMSStoreManager method isObjectInserted.

/**
 * Accessor for whether the specified field of the object is inserted in the datastore yet.
 * @param op ObjectProvider for the object
 * @param fieldNumber (Absolute) field number for the object
 * @return Whether it is persistent
 */
public boolean isObjectInserted(ObjectProvider op, int fieldNumber) {
    if (op == null) {
        return false;
    }
    if (!op.isInserting()) {
        // StateManager isn't inserting so must be persistent
        return true;
    }
    DatastoreClass latestTable = insertedDatastoreClassByObjectProvider.get(op);
    if (latestTable == null) {
        // Not yet inserted anything
        return false;
    }
    AbstractMemberMetaData mmd = op.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
    if (mmd == null) {
        // Specified field doesn't exist for this object type!
        return false;
    }
    String className = mmd.getClassName();
    if (mmd.isPrimaryKey()) {
        // PK field so need to check if the latestTable manages the actual class here
        className = op.getObject().getClass().getName();
    }
    DatastoreClass datastoreCls = latestTable;
    while (datastoreCls != null) {
        if (datastoreCls.managesClass(className)) {
            // This datastore class manages the specified class so it is inserted
            return true;
        }
        datastoreCls = datastoreCls.getSuperDatastoreClass();
    }
    return false;
}
Also used : DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) MacroString(org.datanucleus.util.MacroString) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 32 with DatastoreClass

use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.

the class RDBMSStoreManager method getTableForStrategy.

private DatastoreClass getTableForStrategy(AbstractClassMetaData cmd, int fieldNumber, ClassLoaderResolver clr) {
    DatastoreClass t = getDatastoreClass(cmd.getFullClassName(), clr);
    if (t == null && cmd.getInheritanceMetaData().getStrategy() == InheritanceStrategy.SUBCLASS_TABLE) {
        throw new NucleusUserException(Localiser.msg("032013", cmd.getFullClassName()));
    }
    if (t == null) {
        throw new NucleusUserException("Attempt to find table for class=" + cmd.getFullClassName() + " but no table found! Check the metadata");
    }
    if (fieldNumber >= 0) {
        AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
        t = t.getBaseDatastoreClassWithMember(mmd);
    } else {
        // Go up to overall superclass to find id for that class.
        boolean hasSuperclass = true;
        while (hasSuperclass) {
            DatastoreClass supert = t.getSuperDatastoreClass();
            if (supert != null) {
                t = supert;
            } else {
                hasSuperclass = false;
            }
        }
    }
    return t;
}
Also used : NucleusUserException(org.datanucleus.exceptions.NucleusUserException) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 33 with DatastoreClass

use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.

the class RDBMSStoreManager method getPropertiesForValueGenerator.

/**
 * Method to return the properties to pass to the ValueGenerator for the specified field.
 * @param cmd MetaData for the class
 * @param absoluteFieldNumber Number of the field (-1 = datastore identity)
 * @param clr ClassLoader resolver
 * @param seqmd Any sequence metadata
 * @param tablegenmd Any table generator metadata
 * @return The properties to use for this field
 */
protected Properties getPropertiesForValueGenerator(AbstractClassMetaData cmd, int absoluteFieldNumber, ClassLoaderResolver clr, SequenceMetaData seqmd, TableGeneratorMetaData tablegenmd) {
    AbstractMemberMetaData mmd = null;
    ValueGenerationStrategy strategy = null;
    String sequence = null;
    Map<String, String> extensions = null;
    if (absoluteFieldNumber >= 0) {
        // real field
        mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(absoluteFieldNumber);
        strategy = mmd.getValueStrategy();
        sequence = mmd.getSequence();
        extensions = mmd.getExtensions();
    } else {
        // datastore-identity surrogate field
        // always use the root IdentityMetaData since the root class defines the identity
        IdentityMetaData idmd = cmd.getBaseIdentityMetaData();
        strategy = idmd.getValueStrategy();
        sequence = idmd.getSequence();
        extensions = idmd.getExtensions();
    }
    // Get base table with the required field
    DatastoreClass tbl = getDatastoreClass(cmd.getBaseAbstractClassMetaData().getFullClassName(), clr);
    if (tbl == null) {
        tbl = getTableForStrategy(cmd, absoluteFieldNumber, clr);
    }
    JavaTypeMapping m = null;
    if (mmd != null) {
        m = tbl.getMemberMapping(mmd);
        if (m == null) {
            // Field not mapped in root table so use passed-in table
            tbl = getTableForStrategy(cmd, absoluteFieldNumber, clr);
            m = tbl.getMemberMapping(mmd);
        }
    } else {
        m = tbl.getIdMapping();
    }
    StringBuilder columnsName = new StringBuilder();
    for (int i = 0; i < m.getNumberOfDatastoreMappings(); i++) {
        if (i > 0) {
            columnsName.append(",");
        }
        columnsName.append(m.getDatastoreMapping(i).getColumn().getIdentifier().toString());
    }
    Properties properties = new Properties();
    properties.setProperty(ValueGenerator.PROPERTY_CLASS_NAME, cmd.getFullClassName());
    properties.put(ValueGenerator.PROPERTY_ROOT_CLASS_NAME, cmd.getBaseAbstractClassMetaData().getFullClassName());
    if (mmd != null) {
        properties.setProperty(ValueGenerator.PROPERTY_FIELD_NAME, mmd.getFullFieldName());
    }
    if (cmd.getCatalog() != null) {
        properties.setProperty(ValueGenerator.PROPERTY_CATALOG_NAME, cmd.getCatalog());
    } else if (!StringUtils.isWhitespace(catalogName)) {
        properties.setProperty(ValueGenerator.PROPERTY_CATALOG_NAME, catalogName);
    }
    if (cmd.getSchema() != null) {
        properties.setProperty(ValueGenerator.PROPERTY_SCHEMA_NAME, cmd.getSchema());
    } else if (!StringUtils.isWhitespace(schemaName)) {
        properties.setProperty(ValueGenerator.PROPERTY_SCHEMA_NAME, schemaName);
    }
    properties.setProperty(ValueGenerator.PROPERTY_TABLE_NAME, tbl.getIdentifier().toString());
    properties.setProperty(ValueGenerator.PROPERTY_COLUMN_NAME, columnsName.toString());
    if (sequence != null) {
        properties.setProperty(ValueGenerator.PROPERTY_SEQUENCE_NAME, sequence);
    }
    // Add any extension properties
    if (extensions != null && extensions.size() > 0) {
        properties.putAll(extensions);
    }
    if (strategy.equals(ValueGenerationStrategy.NATIVE)) {
        String realStrategyName = getValueGenerationStrategyForNative(cmd, absoluteFieldNumber);
        strategy = ValueGenerationStrategy.getIdentityStrategy(realStrategyName);
    }
    if (strategy == ValueGenerationStrategy.INCREMENT && tablegenmd != null) {
        // User has specified a TableGenerator (JPA)
        properties.put(ValueGenerator.PROPERTY_KEY_INITIAL_VALUE, "" + tablegenmd.getInitialValue());
        properties.put(ValueGenerator.PROPERTY_KEY_CACHE_SIZE, "" + tablegenmd.getAllocationSize());
        if (tablegenmd.getTableName() != null) {
            properties.put(ValueGenerator.PROPERTY_SEQUENCETABLE_TABLE, tablegenmd.getTableName());
        }
        if (tablegenmd.getCatalogName() != null) {
            properties.put(ValueGenerator.PROPERTY_SEQUENCETABLE_CATALOG, tablegenmd.getCatalogName());
        }
        if (tablegenmd.getSchemaName() != null) {
            properties.put(ValueGenerator.PROPERTY_SEQUENCETABLE_SCHEMA, tablegenmd.getSchemaName());
        }
        if (tablegenmd.getPKColumnName() != null) {
            properties.put(ValueGenerator.PROPERTY_SEQUENCETABLE_NAME_COLUMN, tablegenmd.getPKColumnName());
        }
        if (tablegenmd.getPKColumnName() != null) {
            properties.put(ValueGenerator.PROPERTY_SEQUENCETABLE_NEXTVAL_COLUMN, tablegenmd.getValueColumnName());
        }
        if (tablegenmd.getPKColumnValue() != null) {
            properties.put(ValueGenerator.PROPERTY_SEQUENCE_NAME, tablegenmd.getPKColumnValue());
        }
        // Using JPA generator so don't enable initial value detection
        properties.remove(ValueGenerator.PROPERTY_TABLE_NAME);
        properties.remove(ValueGenerator.PROPERTY_COLUMN_NAME);
    } else if (strategy == ValueGenerationStrategy.INCREMENT && tablegenmd == null) {
        if (!properties.containsKey(ValueGenerator.PROPERTY_KEY_CACHE_SIZE)) {
            // Use default allocation size
            int allocSize = getIntProperty(PropertyNames.PROPERTY_VALUEGEN_INCREMENT_ALLOCSIZE);
            properties.put(ValueGenerator.PROPERTY_KEY_CACHE_SIZE, "" + allocSize);
        }
    } else if (strategy == ValueGenerationStrategy.SEQUENCE && seqmd != null) {
        // User has specified a SequenceGenerator (JDO/JPA)
        if (seqmd.getSchemaName() != null) {
            properties.put(ValueGenerator.PROPERTY_SEQUENCETABLE_SCHEMA, seqmd.getSchemaName());
        }
        if (seqmd.getCatalogName() != null) {
            properties.put(ValueGenerator.PROPERTY_SEQUENCETABLE_CATALOG, seqmd.getCatalogName());
        }
        if (StringUtils.isWhitespace(sequence)) {
            // Apply default to sequence name, as name of sequence metadata
            if (seqmd.getName() != null) {
                properties.put(ValueGenerator.PROPERTY_SEQUENCE_NAME, seqmd.getName());
            }
        }
        if (seqmd.getDatastoreSequence() != null) {
            if (seqmd.getInitialValue() >= 0) {
                properties.put(ValueGenerator.PROPERTY_KEY_INITIAL_VALUE, "" + seqmd.getInitialValue());
            }
            if (seqmd.getAllocationSize() > 0) {
                properties.put(ValueGenerator.PROPERTY_KEY_CACHE_SIZE, "" + seqmd.getAllocationSize());
            } else {
                // Use default allocation size
                int allocSize = getIntProperty(PropertyNames.PROPERTY_VALUEGEN_SEQUENCE_ALLOCSIZE);
                properties.put(ValueGenerator.PROPERTY_KEY_CACHE_SIZE, "" + allocSize);
            }
            properties.put(ValueGenerator.PROPERTY_SEQUENCE_NAME, "" + seqmd.getDatastoreSequence());
            // Add on any extensions specified on the sequence
            Map<String, String> seqExtensions = seqmd.getExtensions();
            if (seqExtensions != null && seqExtensions.size() > 0) {
                properties.putAll(seqExtensions);
            }
        } else {
        // JDO Factory-based sequence generation
        // TODO Support this
        }
    }
    return properties;
}
Also used : JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) ValueGenerationStrategy(org.datanucleus.metadata.ValueGenerationStrategy) MacroString(org.datanucleus.util.MacroString) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) Properties(java.util.Properties) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) IdentityMetaData(org.datanucleus.metadata.IdentityMetaData)

Example 34 with DatastoreClass

use of org.datanucleus.store.rdbms.table.DatastoreClass 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)

Example 35 with DatastoreClass

use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.

the class RDBMSPersistenceHandler method insertObjectInTable.

/**
 * Convenience method to handle the insert into the various tables that this object is persisted into.
 * @param table The table to process
 * @param op ObjectProvider for the object being inserted
 * @param clr ClassLoader resolver
 */
private void insertObjectInTable(DatastoreClass table, ObjectProvider op, ClassLoaderResolver clr) {
    if (table instanceof ClassView) {
        throw new NucleusUserException("Cannot perform InsertRequest on RDBMS view " + table);
    }
    DatastoreClass supertable = table.getSuperDatastoreClass();
    if (supertable != null) {
        // Process the superclass table first
        insertObjectInTable(supertable, op, clr);
    }
    // Do the actual insert of this table
    getInsertRequest(table, op.getClassMetaData(), clr).execute(op);
    // Process any secondary tables
    Collection<SecondaryDatastoreClass> secondaryTables = table.getSecondaryDatastoreClasses();
    if (secondaryTables != null) {
        for (SecondaryDatastoreClass secTable : secondaryTables) {
            // Process the secondary table
            insertObjectInTable(secTable, op, clr);
        }
    }
}
Also used : ClassView(org.datanucleus.store.rdbms.table.ClassView) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) SecondaryDatastoreClass(org.datanucleus.store.rdbms.table.SecondaryDatastoreClass) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) SecondaryDatastoreClass(org.datanucleus.store.rdbms.table.SecondaryDatastoreClass)

Aggregations

DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)87 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)60 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)49 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)48 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)44 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)41 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)35 SQLTable (org.datanucleus.store.rdbms.sql.SQLTable)32 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)28 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)26 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)21 MapTable (org.datanucleus.store.rdbms.table.MapTable)19 NucleusException (org.datanucleus.exceptions.NucleusException)18 SecondaryDatastoreClass (org.datanucleus.store.rdbms.table.SecondaryDatastoreClass)15 ArrayList (java.util.ArrayList)14 ExecutionContext (org.datanucleus.ExecutionContext)13 JoinTable (org.datanucleus.store.rdbms.table.JoinTable)13 Table (org.datanucleus.store.rdbms.table.Table)13 NucleusDataStoreException (org.datanucleus.exceptions.NucleusDataStoreException)11 UnboundExpression (org.datanucleus.store.rdbms.sql.expression.UnboundExpression)11