Search in sources :

Example 1 with ValueGenerationStrategy

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

the class MappingManagerImpl method createDatastoreMapping.

/**
 * Method to create the datastore mapping for a java type mapping at a particular index.
 * @param mapping The java mapping
 * @param mmd MetaData for the field/property
 * @param index Index of the column
 * @param column The column
 * @return The datastore mapping
 */
public DatastoreMapping createDatastoreMapping(JavaTypeMapping mapping, AbstractMemberMetaData mmd, int index, Column column) {
    Class datastoreMappingClass = null;
    if (mmd.getColumnMetaData().length > 0) {
        // Use "datastore-mapping-class" extension if provided
        if (mmd.getColumnMetaData()[index].hasExtension("datastore-mapping-class")) {
            datastoreMappingClass = clr.classForName(mmd.getColumnMetaData()[index].getValueForExtension("datastore-mapping-class"));
        }
    }
    if (datastoreMappingClass == null) {
        String javaType = mapping.getJavaTypeForDatastoreMapping(index);
        String jdbcType = null;
        String sqlType = null;
        if (mapping.getRoleForMember() == FieldRole.ROLE_ARRAY_ELEMENT || mapping.getRoleForMember() == FieldRole.ROLE_COLLECTION_ELEMENT) {
            // Element of a collection/array
            ColumnMetaData[] colmds = (mmd.getElementMetaData() != null ? mmd.getElementMetaData().getColumnMetaData() : null);
            if (colmds != null && colmds.length > 0) {
                jdbcType = colmds[index].getJdbcTypeName();
                sqlType = colmds[index].getSqlType();
            }
            if (mmd.getCollection() != null && mmd.getCollection().isSerializedElement()) {
                javaType = ClassNameConstants.JAVA_IO_SERIALIZABLE;
            }
            if (mmd.getArray() != null && mmd.getArray().isSerializedElement()) {
                javaType = ClassNameConstants.JAVA_IO_SERIALIZABLE;
            }
        } else if (mapping.getRoleForMember() == FieldRole.ROLE_MAP_KEY) {
            // Key of a map
            ColumnMetaData[] colmds = (mmd.getKeyMetaData() != null ? mmd.getKeyMetaData().getColumnMetaData() : null);
            if (colmds != null && colmds.length > 0) {
                jdbcType = colmds[index].getJdbcTypeName();
                sqlType = colmds[index].getSqlType();
            }
            if (mmd.getMap().isSerializedKey()) {
                javaType = ClassNameConstants.JAVA_IO_SERIALIZABLE;
            }
        } else if (mapping.getRoleForMember() == FieldRole.ROLE_MAP_VALUE) {
            // Value of a map
            ColumnMetaData[] colmds = (mmd.getValueMetaData() != null ? mmd.getValueMetaData().getColumnMetaData() : null);
            if (colmds != null && colmds.length > 0) {
                jdbcType = colmds[index].getJdbcTypeName();
                sqlType = colmds[index].getSqlType();
            }
            if (mmd.getMap().isSerializedValue()) {
                javaType = ClassNameConstants.JAVA_IO_SERIALIZABLE;
            }
        } else {
            // Normal field
            if (mmd.getColumnMetaData().length > 0) {
                // Utilise the jdbc and sql types if specified
                jdbcType = mmd.getColumnMetaData()[index].getJdbcTypeName();
                sqlType = mmd.getColumnMetaData()[index].getSqlType();
            }
            // Special case where we have IDENTITY strategy and the datastore imposes a limitation on the required datastore type
            ValueGenerationStrategy strategy = mmd.getValueStrategy();
            if (strategy != null) {
                String strategyName = strategy.toString();
                if (strategy == ValueGenerationStrategy.NATIVE) {
                    strategyName = storeMgr.getValueGenerationStrategyForNative(mmd.getAbstractClassMetaData(), mmd.getAbsoluteFieldNumber());
                }
                if (strategyName != null && ValueGenerationStrategy.IDENTITY.toString().equals(strategyName)) {
                    Class requestedType = clr.classForName(javaType);
                    Class requiredType = storeMgr.getDatastoreAdapter().getAutoIncrementJavaTypeForType(requestedType);
                    if (requiredType != mmd.getType()) {
                        NucleusLogger.DATASTORE_SCHEMA.debug("Member " + mmd.getFullFieldName() + " uses IDENTITY strategy and rather than using memberType of " + mmd.getTypeName() + " for the column type, using " + requiredType + " since the datastore requires that");
                    }
                    javaType = requiredType.getName();
                }
            }
            if (mmd.isSerialized()) {
                javaType = ClassNameConstants.JAVA_IO_SERIALIZABLE;
            }
        }
        datastoreMappingClass = storeMgr.getDatastoreAdapter().getDatastoreMappingClass(javaType, jdbcType, sqlType, clr, mmd.getFullFieldName());
    }
    DatastoreMapping datastoreMapping = DatastoreMappingFactory.createMapping(datastoreMappingClass, mapping, storeMgr, column);
    if (column != null) {
        column.setDatastoreMapping(datastoreMapping);
    }
    return datastoreMapping;
}
Also used : DatastoreMapping(org.datanucleus.store.rdbms.mapping.datastore.DatastoreMapping) ValueGenerationStrategy(org.datanucleus.metadata.ValueGenerationStrategy) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) ColumnMetaData(org.datanucleus.metadata.ColumnMetaData)

Example 2 with ValueGenerationStrategy

use of org.datanucleus.metadata.ValueGenerationStrategy 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) {
    Properties properties = new Properties();
    properties.setProperty(ValueGenerator.PROPERTY_CLASS_NAME, cmd.getFullClassName());
    properties.setProperty(ValueGenerator.PROPERTY_ROOT_CLASS_NAME, cmd.getBaseAbstractClassMetaData().getFullClassName());
    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);
    }
    AbstractMemberMetaData mmd = null;
    ValueGenerationStrategy strategy = null;
    String sequence = null;
    Map<String, String> extensions = null;
    if (absoluteFieldNumber >= 0) {
        // real field
        mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(absoluteFieldNumber);
        properties.setProperty(ValueGenerator.PROPERTY_FIELD_NAME, mmd.getFullFieldName());
        strategy = mmd.getValueStrategy();
        if (strategy.equals(ValueGenerationStrategy.NATIVE)) {
            strategy = ValueGenerationStrategy.getIdentityStrategy(getValueGenerationStrategyForNative(mmd));
        }
        sequence = mmd.getSequence();
        if (sequence != null) {
            properties.setProperty(ValueGenerator.PROPERTY_SEQUENCE_NAME, sequence);
        }
        extensions = mmd.getExtensions();
        if (extensions != null && extensions.size() > 0) {
            properties.putAll(extensions);
        }
    } else {
        // datastore-identity surrogate field
        // always use the root IdentityMetaData since the root class defines the identity
        DatastoreIdentityMetaData idmd = cmd.getBaseDatastoreIdentityMetaData();
        strategy = idmd.getValueStrategy();
        if (strategy.equals(ValueGenerationStrategy.NATIVE)) {
            strategy = ValueGenerationStrategy.getIdentityStrategy(getValueGenerationStrategyForNative(cmd));
        }
        sequence = idmd.getSequence();
        if (sequence != null) {
            properties.setProperty(ValueGenerator.PROPERTY_SEQUENCE_NAME, sequence);
        }
        extensions = idmd.getExtensions();
        if (extensions != null && extensions.size() > 0) {
            properties.putAll(extensions);
        }
    }
    if (strategy != ValueGenerationStrategy.INCREMENT || tablegenmd == null) {
        // 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.getNumberOfColumnMappings(); i++) {
            if (i > 0) {
                columnsName.append(",");
            }
            columnsName.append(m.getColumnMapping(i).getColumn().getIdentifier().toString());
        }
        properties.setProperty(ValueGenerator.PROPERTY_TABLE_NAME, tbl.getIdentifier().toString());
        properties.setProperty(ValueGenerator.PROPERTY_COLUMN_NAME, columnsName.toString());
    }
    if (strategy == ValueGenerationStrategy.INCREMENT) {
        addValueGenerationPropertiesForIncrement(properties, tablegenmd);
    } else if (strategy == ValueGenerationStrategy.SEQUENCE) {
        addValueGenerationPropertiesForSequence(properties, seqmd);
    }
    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) DatastoreIdentityMetaData(org.datanucleus.metadata.DatastoreIdentityMetaData) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 3 with ValueGenerationStrategy

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

the class PersistableMapping method hasDatastoreAttributedPrimaryKeyValues.

/**
 * Check if one of the primary key fields of the PC has value attributed by the datastore
 * @param mmgr the {@link MetaDataManager}
 * @param srm the {@link StoreManager}
 * @param clr the {@link ClassLoaderResolver}
 * @return true if one of the primary key fields of the PC has value attributed by the datastore
 */
private boolean hasDatastoreAttributedPrimaryKeyValues(MetaDataManager mmgr, StoreManager srm, ClassLoaderResolver clr) {
    boolean hasDatastoreAttributedPrimaryKeyValues = false;
    if (this.mmd != null) {
        if (roleForMember != FieldRole.ROLE_ARRAY_ELEMENT && roleForMember != FieldRole.ROLE_COLLECTION_ELEMENT && roleForMember != FieldRole.ROLE_MAP_KEY && roleForMember != FieldRole.ROLE_MAP_VALUE) {
            // Object is associated to a field (i.e not a join table)
            AbstractClassMetaData cmd = mmgr.getMetaDataForClass(this.mmd.getType(), clr);
            if (cmd.getIdentityType() == IdentityType.APPLICATION) {
                int[] pkMemberPositions = cmd.getPKMemberPositions();
                for (int i = 0; i < pkMemberPositions.length; i++) {
                    int pkMemberPosition = pkMemberPositions[i];
                    ValueGenerationStrategy strategy = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkMemberPosition).getValueStrategy();
                    if (strategy != null) {
                        // if strategy is null, then it's user attributed value
                        hasDatastoreAttributedPrimaryKeyValues |= srm.isValueGenerationStrategyDatastoreAttributed(cmd, pkMemberPosition);
                    }
                }
            }
        }
    }
    return hasDatastoreAttributedPrimaryKeyValues;
}
Also used : ValueGenerationStrategy(org.datanucleus.metadata.ValueGenerationStrategy) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Example 4 with ValueGenerationStrategy

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

the class AbstractStoreManager method getValueGeneratorForMember.

protected synchronized ValueGenerator getValueGeneratorForMember(ClassLoaderResolver clr, AbstractClassMetaData cmd, int absoluteFieldNumber) {
    String memberKey = valueGenerationMgr.getMemberKey(cmd, absoluteFieldNumber);
    // Check if we have a ValueGenerator already created for this member
    ValueGenerator generator = valueGenerationMgr.getValueGeneratorForMemberKey(memberKey);
    if (generator != null) {
        // Return the ValueGenerator already registered against this member "key"
        return generator;
    }
    // No ValueGenerator registered for this memberKey, so need to determine which to use and create it as required.
    String fieldName = null;
    ValueGenerationStrategy strategy = null;
    String sequence = null;
    String valueGeneratorName = null;
    if (absoluteFieldNumber >= 0) {
        // real field
        AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(absoluteFieldNumber);
        fieldName = mmd.getFullFieldName();
        strategy = mmd.getValueStrategy();
        sequence = mmd.getSequence();
        valueGeneratorName = mmd.getValueGeneratorName();
    } else {
        // datastore-identity surrogate field
        fieldName = cmd.getFullClassName() + " (datastore id)";
        strategy = cmd.getIdentityMetaData().getValueStrategy();
        sequence = cmd.getIdentityMetaData().getSequence();
        valueGeneratorName = cmd.getIdentityMetaData().getValueGeneratorName();
    }
    String strategyName = strategy.toString();
    if (strategy.equals(ValueGenerationStrategy.CUSTOM)) {
        // Using a "custom" generator
        strategyName = strategy.getCustomName();
    } else if (strategy.equals(ValueGenerationStrategy.NATIVE)) {
        strategyName = getValueGenerationStrategyForNative(cmd, absoluteFieldNumber);
        strategy = ValueGenerationStrategy.getIdentityStrategy(strategyName);
    }
    // Check for this strategy being a "unique" ValueGenerator, and created if not yet present
    generator = valueGenerationMgr.getUniqueValueGeneratorByName(strategyName);
    if (generator != null) {
        // "unique" ValueGenerator already defined for this strategy, so register it against the member
        valueGenerationMgr.registerValueGeneratorForMemberKey(memberKey, generator);
        return generator;
    }
    // Must be "datastore" specific generator so use plugin mechanism to create one and register against this member "key"
    // Set up the default properties available for all value generators
    // Extract any metadata-based generation information keyed by the "valueGeneratorName"
    TableGeneratorMetaData tableGeneratorMetaData = null;
    SequenceMetaData sequenceMetaData = null;
    if (valueGeneratorName != null) {
        if (strategy == ValueGenerationStrategy.INCREMENT) {
            tableGeneratorMetaData = getMetaDataManager().getMetaDataForTableGenerator(clr, valueGeneratorName);
            if (tableGeneratorMetaData == null) {
                throw new NucleusUserException(Localiser.msg("038005", fieldName, valueGeneratorName));
            }
        } else if (strategy == ValueGenerationStrategy.SEQUENCE) {
            sequenceMetaData = getMetaDataManager().getMetaDataForSequence(clr, valueGeneratorName);
            if (sequenceMetaData == null) {
                throw new NucleusUserException(Localiser.msg("038006", fieldName, valueGeneratorName));
            }
        }
    } else if (strategy == ValueGenerationStrategy.SEQUENCE && sequence != null) {
        // TODO Allow for package name of this class prefix for the sequence name
        sequenceMetaData = getMetaDataManager().getMetaDataForSequence(clr, sequence);
        if (sequenceMetaData == null) {
            // No <sequence> defining the datastore sequence name, so fallback to this name directly in the datastore
            NucleusLogger.VALUEGENERATION.info("Member " + fieldName + " has been specified to use sequence '" + sequence + "' but there is no <sequence> specified in the MetaData. Falling back to use a sequence in the datastore with this name directly.");
        }
    }
    Properties props = getPropertiesForValueGenerator(cmd, absoluteFieldNumber, clr, sequenceMetaData, tableGeneratorMetaData);
    return valueGenerationMgr.createAndRegisterValueGenerator(memberKey, strategyName, props);
}
Also used : NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ValueGenerator(org.datanucleus.store.valuegenerator.ValueGenerator) ValueGenerationStrategy(org.datanucleus.metadata.ValueGenerationStrategy) TableGeneratorMetaData(org.datanucleus.metadata.TableGeneratorMetaData) Properties(java.util.Properties) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) SequenceMetaData(org.datanucleus.metadata.SequenceMetaData)

Example 5 with ValueGenerationStrategy

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

the class StateManagerImpl method populateValueGenerationFields.

/**
 * Convenience method to populate all fields in the PC object that need their value generating (according to metadata) and that aren't datastore-attributed.
 * This applies not just to PK fields (main use-case) but also to any other field (DN extension).
 * Fields can be populated only if they are null dependent on metadata.
 * This method is called once on a PC object, when makePersistent is called.
 */
private void populateValueGenerationFields() {
    int totalFieldCount = cmd.getNoOfInheritedManagedMembers() + cmd.getNoOfManagedMembers();
    for (int fieldNumber = 0; fieldNumber < totalFieldCount; fieldNumber++) {
        AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
        ValueGenerationStrategy strategy = mmd.getValueStrategy();
        // Check for the strategy, and if it is a datastore attributed strategy
        if (strategy != null && !getStoreManager().isValueGenerationStrategyDatastoreAttributed(cmd, fieldNumber)) {
            // Assign the strategy value where required.
            // Default JDO/JPA behaviour is to always provide a strategy value when it is marked as using a strategy
            boolean applyStrategy = true;
            if (!mmd.getType().isPrimitive() && mmd.hasExtension(MetaData.EXTENSION_MEMBER_STRATEGY_WHEN_NOTNULL) && mmd.getValueForExtension(MetaData.EXTENSION_MEMBER_STRATEGY_WHEN_NOTNULL).equalsIgnoreCase("false") && this.provideField(fieldNumber) != null) {
                // extension to only provide a value-strategy value where the field is null at persistence.
                applyStrategy = false;
            }
            if (applyStrategy) {
                // Apply a strategy value for this field
                Object obj = getStoreManager().getValueGenerationStrategyValue(myEC, cmd, fieldNumber);
                this.replaceField(fieldNumber, obj);
            }
        }
    }
}
Also used : ValueGenerationStrategy(org.datanucleus.metadata.ValueGenerationStrategy) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Aggregations

ValueGenerationStrategy (org.datanucleus.metadata.ValueGenerationStrategy)8 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)5 Properties (java.util.Properties)3 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)3 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)2 ColumnMetaData (org.datanucleus.metadata.ColumnMetaData)2 ValueGenerator (org.datanucleus.store.valuegenerator.ValueGenerator)2 NucleusException (org.datanucleus.exceptions.NucleusException)1 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)1 DatastoreIdentityMetaData (org.datanucleus.metadata.DatastoreIdentityMetaData)1 IdentityMetaData (org.datanucleus.metadata.IdentityMetaData)1 SequenceMetaData (org.datanucleus.metadata.SequenceMetaData)1 TableGeneratorMetaData (org.datanucleus.metadata.TableGeneratorMetaData)1 ColumnMapping (org.datanucleus.store.rdbms.mapping.column.ColumnMapping)1 DatastoreMapping (org.datanucleus.store.rdbms.mapping.datastore.DatastoreMapping)1 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)1 MacroString (org.datanucleus.util.MacroString)1