use of org.datanucleus.store.rdbms.exceptions.ClassDefinitionException in project datanucleus-rdbms by datanucleus.
the class ClassTable method initializeFKMapUniqueConstraints.
/**
* Method to initialise unique constraints for 1-N Map using FK.
* @param ownerMmd metadata for the field/property with the map in the owner class
*/
private void initializeFKMapUniqueConstraints(AbstractMemberMetaData ownerMmd) {
// Load "mapped-by"
AbstractMemberMetaData mfmd = null;
// Field in our class that maps back to the owner class
String map_field_name = ownerMmd.getMappedBy();
if (map_field_name != null) {
// Bidirectional
mfmd = cmd.getMetaDataForMember(map_field_name);
if (mfmd == null) {
// Field not in primary class so may be in subclass so check all managed classes
Iterator<AbstractClassMetaData> cmdIter = managedClassMetaData.iterator();
while (cmdIter.hasNext()) {
AbstractClassMetaData managedCmd = cmdIter.next();
mfmd = managedCmd.getMetaDataForMember(map_field_name);
if (mfmd != null) {
break;
}
}
}
if (mfmd == null) {
// "mapped-by" refers to a field in our class that doesnt exist!
throw new NucleusUserException(Localiser.msg("057036", map_field_name, cmd.getFullClassName(), ownerMmd.getFullFieldName()));
}
if (ownerMmd.getJoinMetaData() == null) {
// Load field of key in value
if (ownerMmd.getKeyMetaData() != null && ownerMmd.getKeyMetaData().getMappedBy() != null) {
// Key field is stored in the value table
AbstractMemberMetaData kmd = null;
String key_field_name = ownerMmd.getKeyMetaData().getMappedBy();
if (key_field_name != null) {
kmd = cmd.getMetaDataForMember(key_field_name);
}
if (kmd == null) {
// Field not in primary class so may be in subclass so check all managed classes
Iterator<AbstractClassMetaData> cmdIter = managedClassMetaData.iterator();
while (cmdIter.hasNext()) {
AbstractClassMetaData managedCmd = cmdIter.next();
kmd = managedCmd.getMetaDataForMember(key_field_name);
if (kmd != null) {
break;
}
}
}
if (kmd == null) {
throw new ClassDefinitionException(Localiser.msg("057007", mfmd.getFullFieldName(), key_field_name));
}
JavaTypeMapping ownerMapping = getMemberMapping(map_field_name);
JavaTypeMapping keyMapping = getMemberMapping(kmd.getName());
if (dba.supportsOption(DatastoreAdapter.NULLS_IN_CANDIDATE_KEYS) || (!ownerMapping.isNullable() && !keyMapping.isNullable())) {
// cannot do this so just omit it.
if (keyMapping.getTable() == this && ownerMapping.getTable() == this) {
CandidateKey ck = new CandidateKey(this, null);
// This HashSet is to avoid duplicate adding of columns.
HashSet addedColumns = new HashSet();
// Add columns for the owner field
int countOwnerFields = ownerMapping.getNumberOfColumnMappings();
for (int i = 0; i < countOwnerFields; i++) {
Column col = ownerMapping.getColumnMapping(i).getColumn();
addedColumns.add(col);
ck.addColumn(col);
}
// Add columns for the key field
int countKeyFields = keyMapping.getNumberOfColumnMappings();
for (int i = 0; i < countKeyFields; i++) {
Column col = keyMapping.getColumnMapping(i).getColumn();
if (!addedColumns.contains(col)) {
addedColumns.add(col);
ck.addColumn(col);
} else {
NucleusLogger.DATASTORE_SCHEMA.warn(Localiser.msg("057041", ownerMmd.getName()));
}
}
if (candidateKeysByMapField.put(mfmd, ck) != null) {
// We have multiple "mapped-by" coming to this field so give a warning that this may potentially
// cause problems. For example if they have the key field defined here for 2 different relations
// so you may get keys/values appearing in the other relation that shouldn't be.
// Logged as a WARNING for now.
// If there is a situation where this should throw an exception, please update this AND COMMENT WHY.
NucleusLogger.DATASTORE_SCHEMA.warn(Localiser.msg("057012", mfmd.getFullFieldName(), ownerMmd.getFullFieldName()));
}
}
}
} else if (ownerMmd.getValueMetaData() != null && ownerMmd.getValueMetaData().getMappedBy() != null) {
// Value field is stored in the key table
AbstractMemberMetaData vmd = null;
String value_field_name = ownerMmd.getValueMetaData().getMappedBy();
if (value_field_name != null) {
vmd = cmd.getMetaDataForMember(value_field_name);
}
if (vmd == null) {
throw new ClassDefinitionException(Localiser.msg("057008", mfmd));
}
JavaTypeMapping ownerMapping = getMemberMapping(map_field_name);
JavaTypeMapping valueMapping = getMemberMapping(vmd.getName());
if (dba.supportsOption(DatastoreAdapter.NULLS_IN_CANDIDATE_KEYS) || (!ownerMapping.isNullable() && !valueMapping.isNullable())) {
// cannot do this so just omit it.
if (valueMapping.getTable() == this && ownerMapping.getTable() == this) {
CandidateKey ck = new CandidateKey(this, null);
// This HashSet is to avoid duplicate adding of columns.
Set<Column> addedColumns = new HashSet<>();
// Add columns for the owner field
int countOwnerFields = ownerMapping.getNumberOfColumnMappings();
for (int i = 0; i < countOwnerFields; i++) {
Column col = ownerMapping.getColumnMapping(i).getColumn();
addedColumns.add(col);
ck.addColumn(col);
}
// Add columns for the value field
int countValueFields = valueMapping.getNumberOfColumnMappings();
for (int i = 0; i < countValueFields; i++) {
Column col = valueMapping.getColumnMapping(i).getColumn();
if (!addedColumns.contains(col)) {
addedColumns.add(col);
ck.addColumn(col);
} else {
NucleusLogger.DATASTORE_SCHEMA.warn(Localiser.msg("057042", ownerMmd.getName()));
}
}
if (candidateKeysByMapField.put(mfmd, ck) != null) {
// We have multiple "mapped-by" coming to this field so give a warning that this may potentially
// cause problems. For example if they have the key field defined here for 2 different relations
// so you may get keys/values appearing in the other relation that shouldn't be.
// Logged as a WARNING for now.
// If there is a situation where this should throw an exception, please update this AND COMMENT WHY.
NucleusLogger.DATASTORE_SCHEMA.warn(Localiser.msg("057012", mfmd.getFullFieldName(), ownerMmd.getFullFieldName()));
}
}
}
} else {
// We can only have either the key stored in the value or the value stored in the key but nothing else!
throw new ClassDefinitionException(Localiser.msg("057009", ownerMmd.getFullFieldName()));
}
}
}
}
Aggregations