use of org.datanucleus.store.rdbms.exceptions.NoTableManagedException in project datanucleus-rdbms by datanucleus.
the class ReferenceMapping method createPerImplementationColumnsForReferenceField.
/**
* Create columns for reference (Interface/Object) fields on a per-implementation basis.
* This call ColumnCreator.createColumnsForField for each implementation class of the reference.
*/
void createPerImplementationColumnsForReferenceField(boolean pk, boolean nullable, boolean serialised, boolean embedded, FieldRole fieldRole, ColumnMetaData[] columnMetaData, ClassLoaderResolver clr) {
if (this instanceof InterfaceMapping && mmd.hasExtension(MetaData.EXTENSION_MEMBER_IMPLEMENTATION_CLASSES)) {
// Store the implementation-classes with the mapping (persistent interfaces?)
((InterfaceMapping) this).setImplementationClasses(mmd.getValueForExtension(MetaData.EXTENSION_MEMBER_IMPLEMENTATION_CLASSES));
}
// Find the available implementations that we are creating columns for
String[] implTypes = null;
try {
implTypes = MetaDataUtils.getInstance().getImplementationNamesForReferenceField(mmd, fieldRole, clr, storeMgr.getMetaDataManager());
} catch (NucleusUserException nue) {
// No implementation classes found, so log warning and return
if (storeMgr.getBooleanProperty(PropertyNames.PROPERTY_STORE_ALLOW_REFS_WITHOUT_IMPLS, false)) {
NucleusLogger.DATASTORE_SCHEMA.warn("Possible problem encountered while adding columns for field " + mmd.getFullFieldName() + " : " + nue.getMessage());
return;
}
throw nue;
}
// Set the PK and nullability of column(s) for the implementations (based on the number of impls etc)
if (implTypes.length > 1) {
// Cannot be part of PK if more than 1 implementation
pk = false;
}
if (implTypes.length > 1 && !pk) {
// Must be nullable if more than 1 impl (since only 1 impl can have value at a time)
nullable = true;
}
// Create list of classes that require columns.
// We only add columns for the implementation that is the root of a particular inheritance tree
// e.g if we have A implements I1, and B extends A then they both are valid implementations
// but we only want to create column(s) for A.
Collection implClasses = new ArrayList();
for (int i = 0; i < implTypes.length; i++) {
Class type = clr.classForName(implTypes[i]);
if (type == null) {
throw new NucleusUserException(Localiser.msg("020189", mmd.getTypeName(), implTypes[i]));
} else if (type.isInterface()) {
throw new NucleusUserException(Localiser.msg("020190", mmd.getFullFieldName(), mmd.getTypeName(), implTypes[i]));
}
Iterator iter = implClasses.iterator();
boolean toBeAdded = true;
Class clsToSwap = null;
while (iter.hasNext()) {
Class cls = (Class) iter.next();
if (cls == type) {
// Implementation already present
toBeAdded = false;
break;
}
if (type.isAssignableFrom(cls)) {
// "type" is superclass of "cls" so swap subclass for this class
clsToSwap = cls;
toBeAdded = false;
break;
} else if (cls.isAssignableFrom(type)) {
toBeAdded = false;
break;
}
}
if (toBeAdded) {
implClasses.add(type);
} else if (clsToSwap != null) {
implClasses.remove(clsToSwap);
implClasses.add(type);
}
}
// Add columns for each of these implementations
int colPos = 0;
Iterator implClsIter = implClasses.iterator();
while (implClsIter.hasNext()) {
Class implClass = (Class) implClsIter.next();
boolean present = false;
int numJavaTypeMappings = getJavaTypeMapping().length;
for (int i = 0; i < numJavaTypeMappings; i++) {
JavaTypeMapping implMapping = getJavaTypeMapping()[i];
if (implClass.getName().equals(implMapping.getType())) {
present = true;
}
}
if (present) {
// Implementation already present in mapping (e.g reinitialising) so skip this
continue;
}
String fieldTypeName = getReferenceFieldType(fieldRole);
boolean isPersistentInterfaceField = storeMgr.getNucleusContext().getMetaDataManager().isPersistentInterface(fieldTypeName);
boolean columnsNeeded = true;
if (isPersistentInterfaceField && !storeMgr.getNucleusContext().getMetaDataManager().isPersistentInterfaceImplementation(fieldTypeName, implClass.getName())) {
// We have a "persistent-interface" field yet this is not a generated implementation so ignore it
// It is arguable if we should allow the real implementations of this interface here, but the JDO2 TCK doesn't
// make that assumption so we don't either
columnsNeeded = false;
}
if (columnsNeeded) {
// Get the mapping for this implementation
JavaTypeMapping m;
if (storeMgr.getMappingManager().isSupportedMappedType(implClass.getName())) {
m = storeMgr.getMappingManager().getMapping(implClass, serialised, embedded, mmd.getFullFieldName());
} else {
try {
DatastoreClass dc = storeMgr.getDatastoreClass(implClass.getName(), clr);
m = dc.getIdMapping();
} catch (NoTableManagedException ex) {
// TODO Localise this message
throw new NucleusUserException("Cannot define columns for " + mmd.getFullFieldName() + " due to " + ex.getMessage(), ex);
}
}
ColumnMetaData[] columnMetaDataForType = null;
if (columnMetaData != null && columnMetaData.length > 0) {
if (columnMetaData.length < colPos + m.getNumberOfDatastoreMappings()) {
throw new NucleusUserException(Localiser.msg("020186", mmd.getFullFieldName(), "" + columnMetaData.length, "" + (colPos + m.getNumberOfDatastoreMappings())));
}
columnMetaDataForType = new ColumnMetaData[m.getNumberOfDatastoreMappings()];
System.arraycopy(columnMetaData, colPos, columnMetaDataForType, 0, columnMetaDataForType.length);
colPos += columnMetaDataForType.length;
}
// Create the FK column(s) for this implementation
ColumnCreator.createColumnsForField(implClass, this, table, storeMgr, mmd, pk, nullable, serialised, embedded, fieldRole, columnMetaDataForType, clr, true, null);
if (NucleusLogger.DATASTORE.isInfoEnabled()) {
NucleusLogger.DATASTORE.info(Localiser.msg("020188", implClass, mmd.getName()));
}
}
}
}
use of org.datanucleus.store.rdbms.exceptions.NoTableManagedException in project datanucleus-rdbms by datanucleus.
the class ElementContainerTable method getExpectedForeignKeys.
/**
* Accessor for the expected foreign keys for this table.
* @param clr The ClassLoaderResolver
* @return The expected foreign keys.
*/
public List getExpectedForeignKeys(ClassLoaderResolver clr) {
assertIsInitialized();
// Find the mode that we're operating in for FK addition
boolean autoMode = false;
if (storeMgr.getStringProperty(RDBMSPropertyNames.PROPERTY_RDBMS_CONSTRAINT_CREATE_MODE).equals("DataNucleus")) {
autoMode = true;
}
ArrayList foreignKeys = new ArrayList();
try {
// FK from join table to owner table
DatastoreClass referencedTable = storeMgr.getDatastoreClass(ownerType, clr);
if (referencedTable != null) {
// Single owner table, so add a single FK to the owner as appropriate
ForeignKey fk = getForeignKeyToOwner(referencedTable, autoMode);
if (fk != null) {
foreignKeys.add(fk);
}
} else {
// No single owner so we don't bother with the FK since referential integrity by FK cannot work
// if we don't have a single owner at the other end of the FK(s).
}
// FK from join table to element table(s)
if (elementMapping instanceof SerialisedPCMapping) {
// Do nothing since no element table
} else if (elementMapping instanceof EmbeddedElementPCMapping) {
// Add any FKs for the fields of the (embedded) element
EmbeddedElementPCMapping embMapping = (EmbeddedElementPCMapping) elementMapping;
for (int i = 0; i < embMapping.getNumberOfJavaTypeMappings(); i++) {
JavaTypeMapping embFieldMapping = embMapping.getJavaTypeMapping(i);
AbstractMemberMetaData embFmd = embFieldMapping.getMemberMetaData();
if (ClassUtils.isReferenceType(embFmd.getType()) && embFieldMapping instanceof ReferenceMapping) {
// Field is a reference type, so add a FK to the table of the PC for each PC implementation
Collection fks = TableUtils.getForeignKeysForReferenceField(embFieldMapping, embFmd, autoMode, storeMgr, clr);
foreignKeys.addAll(fks);
} else if (storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(embFmd.getType(), clr) != null && embFieldMapping.getNumberOfDatastoreMappings() > 0 && embFieldMapping instanceof PersistableMapping) {
// Field is for a PC class with the FK at this side, so add a FK to the table of this PC
ForeignKey fk = TableUtils.getForeignKeyForPCField(embFieldMapping, embFmd, autoMode, storeMgr, clr);
if (fk != null) {
foreignKeys.add(fk);
}
}
}
} else if (elementMapping instanceof ReferenceMapping) {
JavaTypeMapping[] implJavaTypeMappings = ((ReferenceMapping) elementMapping).getJavaTypeMapping();
for (int i = 0; i < implJavaTypeMappings.length; i++) {
JavaTypeMapping implMapping = implJavaTypeMappings[i];
if (storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(implMapping.getType(), clr) != null && implMapping.getNumberOfDatastoreMappings() > 0) {
referencedTable = storeMgr.getDatastoreClass(implMapping.getType(), clr);
if (referencedTable != null) {
ForeignKey fk = getForeignKeyToElement(referencedTable, autoMode, implMapping);
if (fk != null) {
foreignKeys.add(fk);
}
}
}
}
} else {
referencedTable = storeMgr.getDatastoreClass(getElementType(), clr);
if (referencedTable != null) {
ForeignKey fk = getForeignKeyToElement(referencedTable, autoMode, elementMapping);
if (fk != null) {
foreignKeys.add(fk);
}
} else {
// Either no element table or multiple (where the user has element with "subclass-table" strategy, or using "complete-table")
// so do nothing since referential integrity will not allow multiple FKs.
}
}
} catch (NoTableManagedException e) {
// expected when no table exists
}
return foreignKeys;
}
use of org.datanucleus.store.rdbms.exceptions.NoTableManagedException in project datanucleus-rdbms by datanucleus.
the class ElementContainerTable method initialize.
/**
* Method to initialise the table definition. Adds the owner mapping.
* @param clr The ClassLoaderResolver
*/
public void initialize(ClassLoaderResolver clr) {
assertIsUninitialized();
// Add owner mapping
AbstractMemberMetaData[] relatedMmds = mmd.getRelatedMemberMetaData(clr);
ColumnMetaData[] columnMetaData = null;
if (mmd.getJoinMetaData() != null && mmd.getJoinMetaData().getColumnMetaData() != null && mmd.getJoinMetaData().getColumnMetaData().length > 0) {
// Column mappings defined at this side (1-N, M-N)
// When specified at this side they use the <join> tag
columnMetaData = mmd.getJoinMetaData().getColumnMetaData();
} else if (relatedMmds != null && relatedMmds[0].getElementMetaData() != null && relatedMmds[0].getElementMetaData().getColumnMetaData() != null && relatedMmds[0].getElementMetaData().getColumnMetaData().length > 0) {
// Column mappings defined at other side (M-N)
// When specified at other side they use the <element> tag
// ** This is really only for Collections/Sets since M-N doesnt make sense for indexed Lists/arrays **
columnMetaData = relatedMmds[0].getElementMetaData().getColumnMetaData();
}
try {
ownerMapping = ColumnCreator.createColumnsForJoinTables(clr.classForName(ownerType), mmd, columnMetaData, storeMgr, this, false, false, FieldRole.ROLE_OWNER, clr, ownerTable);
} catch (NoTableManagedException ntme) {
// Maybe this is a join table from an embedded object, so no table to link back to
throw new NucleusUserException("Table " + toString() + " for member=" + mmd.getFullFieldName() + " needs a column to link back to its owner, yet the owner type (" + ownerType + ") has no table of its own (embedded?)");
}
if (NucleusLogger.DATASTORE.isDebugEnabled()) {
logMapping(mmd.getFullFieldName() + ".[OWNER]", ownerMapping);
}
// Add any distinguisher column
if (mmd.hasExtension(MetaData.EXTENSION_MEMBER_RELATION_DISCRIM_COLUMN) || mmd.hasExtension(MetaData.EXTENSION_MEMBER_RELATION_DISCRIM_VALUE)) {
// Generate some columnMetaData for our new column
String colName = mmd.getValueForExtension(MetaData.EXTENSION_MEMBER_RELATION_DISCRIM_COLUMN);
if (colName == null) {
// No column defined so use a fallback name
colName = "RELATION_DISCRIM";
}
ColumnMetaData colmd = new ColumnMetaData();
colmd.setName(colName);
boolean relationDiscriminatorPk = false;
if (mmd.hasExtension(MetaData.EXTENSION_MEMBER_RELATION_DISCRIM_PK) && mmd.getValueForExtension(MetaData.EXTENSION_MEMBER_RELATION_DISCRIM_PK).equalsIgnoreCase("true")) {
// Default this to not be part of the PK of the join table, but allow the user to override it
relationDiscriminatorPk = true;
}
if (!relationDiscriminatorPk) {
// Allow for elements not in any discriminated collection (when not PK)
colmd.setAllowsNull(Boolean.TRUE);
}
// Create the mapping and its datastore column (only support String relation discriminators here)
relationDiscriminatorMapping = storeMgr.getMappingManager().getMapping(String.class);
ColumnCreator.createIndexColumn(relationDiscriminatorMapping, storeMgr, clr, this, colmd, relationDiscriminatorPk);
relationDiscriminatorValue = mmd.getValueForExtension(MetaData.EXTENSION_MEMBER_RELATION_DISCRIM_VALUE);
if (relationDiscriminatorValue == null) {
// No value defined so just use the field name
relationDiscriminatorValue = mmd.getFullFieldName();
}
}
}
use of org.datanucleus.store.rdbms.exceptions.NoTableManagedException 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.exceptions.NoTableManagedException in project datanucleus-rdbms by datanucleus.
the class ClassTable method initializePK.
/**
* Method to initialise the table primary key field(s).
* @param clr The ClassLoaderResolver
*/
protected void initializePK(ClassLoaderResolver clr) {
assertIsPKUninitialized();
AbstractMemberMetaData[] membersToAdd = new AbstractMemberMetaData[cmd.getNoOfPrimaryKeyMembers()];
// Initialise Primary Key mappings for application id with PK fields in this class
int pkFieldNum = 0;
int fieldCount = cmd.getNoOfManagedMembers();
boolean hasPrimaryKeyInThisClass = false;
if (cmd.getNoOfPrimaryKeyMembers() > 0) {
pkMappings = new JavaTypeMapping[cmd.getNoOfPrimaryKeyMembers()];
if (cmd.getInheritanceMetaData().getStrategy() == InheritanceStrategy.COMPLETE_TABLE) {
// COMPLETE-TABLE so use root class metadata and add PK members
// TODO Does this allow for overridden PK field info ?
AbstractClassMetaData baseCmd = cmd.getBaseAbstractClassMetaData();
fieldCount = baseCmd.getNoOfManagedMembers();
for (int relFieldNum = 0; relFieldNum < fieldCount; ++relFieldNum) {
AbstractMemberMetaData mmd = baseCmd.getMetaDataForManagedMemberAtRelativePosition(relFieldNum);
if (mmd.isPrimaryKey()) {
AbstractMemberMetaData overriddenMmd = cmd.getOverriddenMember(mmd.getName());
if (overriddenMmd != null) {
// PK field is overridden so use the overriding definition
mmd = overriddenMmd;
}
if (mmd.getPersistenceModifier() == FieldPersistenceModifier.PERSISTENT) {
membersToAdd[pkFieldNum++] = mmd;
hasPrimaryKeyInThisClass = true;
} else if (mmd.getPersistenceModifier() != FieldPersistenceModifier.TRANSACTIONAL) {
throw new NucleusException(Localiser.msg("057006", mmd.getName())).setFatal();
}
// Check if auto-increment and that it is supported by this RDBMS
if ((mmd.getValueStrategy() == ValueGenerationStrategy.IDENTITY) && !dba.supportsOption(DatastoreAdapter.IDENTITY_COLUMNS)) {
throw new NucleusException(Localiser.msg("057020", cmd.getFullClassName(), mmd.getName())).setFatal();
}
}
}
} else {
for (int relFieldNum = 0; relFieldNum < fieldCount; ++relFieldNum) {
AbstractMemberMetaData fmd = cmd.getMetaDataForManagedMemberAtRelativePosition(relFieldNum);
if (fmd.isPrimaryKey()) {
if (fmd.getPersistenceModifier() == FieldPersistenceModifier.PERSISTENT) {
membersToAdd[pkFieldNum++] = fmd;
hasPrimaryKeyInThisClass = true;
} else if (fmd.getPersistenceModifier() != FieldPersistenceModifier.TRANSACTIONAL) {
throw new NucleusException(Localiser.msg("057006", fmd.getName())).setFatal();
}
// Check if auto-increment and that it is supported by this RDBMS
if ((fmd.getValueStrategy() == ValueGenerationStrategy.IDENTITY) && !dba.supportsOption(DatastoreAdapter.IDENTITY_COLUMNS)) {
throw new NucleusException(Localiser.msg("057020", cmd.getFullClassName(), fmd.getName())).setFatal();
}
}
}
}
}
// No Primary Key defined, so search for superclass or handle datastore id
if (!hasPrimaryKeyInThisClass) {
if (cmd.getIdentityType() == IdentityType.APPLICATION) {
// application-identity
// TODO rewrite this to just use metadata to get the PKs of the superclass(es). Any reason why not?
DatastoreClass superTable = storeMgr.getDatastoreClass(cmd.getPersistableSuperclass(), clr);
if (isPKInitialized()) {
// The above call could have triggered a population of the PK here
return;
}
if (superTable == null && cmd.getPersistableSuperclass() != null) {
// The superclass doesn't have its own table, so keep going up til we find the next table
AbstractClassMetaData supercmd = cmd.getSuperAbstractClassMetaData();
while (true) {
if (supercmd.getPersistableSuperclass() == null) {
break;
}
superTable = storeMgr.getDatastoreClass(supercmd.getPersistableSuperclass(), clr);
if (isPKInitialized()) {
// The above call could have triggered a population of the PK here
return;
}
if (superTable != null) {
break;
}
supercmd = supercmd.getSuperAbstractClassMetaData();
if (supercmd == null) {
break;
}
}
}
if (superTable != null) {
// Superclass has a table so copy its PK mappings
ColumnMetaDataContainer colContainer = null;
if (cmd.getInheritanceMetaData() != null) {
// Try via <inheritance><join>...</join></inheritance>
colContainer = cmd.getInheritanceMetaData().getJoinMetaData();
}
if (colContainer == null) {
// Try via <primary-key>...</primary-key>
colContainer = cmd.getPrimaryKeyMetaData();
}
addApplicationIdUsingClassTableId(colContainer, superTable, clr, cmd);
} else {
// No supertable to copy, so find superclass with PK fields and create new mappings and columns
AbstractClassMetaData pkCmd = getClassWithPrimaryKeyForClass(cmd.getSuperAbstractClassMetaData(), clr);
if (pkCmd != null) {
// TODO Just use cmd.getPKMemberPositions to avoid iteration to find PKs
pkMappings = new JavaTypeMapping[pkCmd.getNoOfPrimaryKeyMembers()];
pkFieldNum = 0;
fieldCount = pkCmd.getNoOfInheritedManagedMembers() + pkCmd.getNoOfManagedMembers();
for (int absFieldNum = 0; absFieldNum < fieldCount; ++absFieldNum) {
AbstractMemberMetaData fmd = pkCmd.getMetaDataForManagedMemberAtAbsolutePosition(absFieldNum);
if (fmd.isPrimaryKey()) {
AbstractMemberMetaData overriddenFmd = cmd.getOverriddenMember(fmd.getName());
if (overriddenFmd != null) {
// PK field is overridden so use the overriding definition
fmd = overriddenFmd;
} else {
AbstractClassMetaData thisCmd = cmd;
while (thisCmd.getSuperAbstractClassMetaData() != null && thisCmd.getSuperAbstractClassMetaData() != pkCmd) {
thisCmd = thisCmd.getSuperAbstractClassMetaData();
overriddenFmd = thisCmd.getOverriddenMember(fmd.getName());
if (overriddenFmd != null) {
// PK field is overridden so use the overriding definition
fmd = overriddenFmd;
break;
}
}
}
if (fmd.getPersistenceModifier() == FieldPersistenceModifier.PERSISTENT) {
membersToAdd[pkFieldNum++] = fmd;
} else if (fmd.getPersistenceModifier() != FieldPersistenceModifier.TRANSACTIONAL) {
throw new NucleusException(Localiser.msg("057006", fmd.getName())).setFatal();
}
}
}
}
}
} else if (cmd.getIdentityType() == IdentityType.DATASTORE) {
// datastore-identity
ColumnMetaData colmd = null;
if (cmd.getIdentityMetaData() != null && cmd.getIdentityMetaData().getColumnMetaData() != null) {
// Try via <datastore-identity>...</datastore-identity>
colmd = cmd.getIdentityMetaData().getColumnMetaData();
}
if (colmd == null) {
// Try via <primary-key>...</primary-key>
if (cmd.getPrimaryKeyMetaData() != null && cmd.getPrimaryKeyMetaData().getColumnMetaData() != null && cmd.getPrimaryKeyMetaData().getColumnMetaData().length > 0) {
colmd = cmd.getPrimaryKeyMetaData().getColumnMetaData()[0];
}
}
addDatastoreId(colmd, null, cmd);
} else if (cmd.getIdentityType() == IdentityType.NONDURABLE) {
// Do nothing since no identity!
}
}
// add field mappings in the end, so we compute all columns after the post initialize
for (int i = 0; i < membersToAdd.length; i++) {
if (membersToAdd[i] != null) {
try {
DatastoreClass datastoreClass = getStoreManager().getDatastoreClass(membersToAdd[i].getType().getName(), clr);
if (datastoreClass.getIdMapping() == null) {
throw new NucleusException("Unsupported relationship with field " + membersToAdd[i].getFullFieldName()).setFatal();
}
} catch (NoTableManagedException ex) {
// do nothing
}
JavaTypeMapping fieldMapping = storeMgr.getMappingManager().getMapping(this, membersToAdd[i], clr, FieldRole.ROLE_FIELD);
addMemberMapping(fieldMapping);
pkMappings[i] = fieldMapping;
}
}
initializeIDMapping();
state = TABLE_STATE_PK_INITIALIZED;
}
Aggregations