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