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;
}
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;
}
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;
}
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);
}
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);
}
}
}
}
Aggregations