// Add a default one for each part of the composite primary
// key. Foreign and primary key to have the same name.
for (DatabaseField primaryKeyField : referenceDescriptor.getPrimaryKeyFields()) {
// Multitenant primary key fields will be dealt with below so avoid adding here.
if (! primaryKeyField.isPrimaryKey()) {
JoinColumnMetadata joinColumn = new JoinColumnMetadata();
joinColumn.setReferencedColumnName(primaryKeyField.getName());
joinColumn.setName(primaryKeyField.getName());
joinColumn.setProject(referenceDescriptor.getProject());
joinColumns.add(joinColumn);
}
}
} else {
// Add a default one for the single case, not setting any
// foreign and primary key names. They will default based
// on which accessor is using them.
JoinColumnMetadata jcm = new JoinColumnMetadata();
jcm.setProject(referenceDescriptor.getProject());
joinColumns.add(jcm);
}
} else {
// Need to update any join columns that use a foreign key name
// for the primary key name. E.G. User specifies the renamed id
// field name from a primary key join column as the primary key in
// an inheritance subclass.
for (JoinColumnMetadata joinColumn : joinColumns) {
// Doing this could potentially change a value entered in XML.
// However, in this case I think that is ok since in theory we
// are writing out the correct value that EclipseLink needs to
// form valid queries.
String referencedColumnName = joinColumn.getReferencedColumnName();
// The referenced column name in a variable one to one case is a
// query key name and not a column name so bypass any of this
// code.
if (referencedColumnName != null && !isVariableOneToOne()) {
DatabaseField referencedField = new DatabaseField();
setFieldName(referencedField, referencedColumnName);
joinColumn.setReferencedColumnName(referenceDescriptor.getPrimaryKeyJoinColumnAssociation(referencedField).getName());
}
}
}
// Multitenant entities. Go through and add any multitenant primary key
// fields that need to be added. The user may or may not specify them
// in metadata.
if (referenceDescriptor.hasSingleTableMultitenant() && joinColumns.size() != referenceDescriptor.getPrimaryKeyFields().size()) {
Map<String, List<DatabaseField>> referenceTenantFields = referenceDescriptor.getSingleTableMultitenantFields();
// If we are multitenant then we can sync up on relationship fields
// using the context property.
Map<String, List<DatabaseField>> tenantFields = getDescriptor().hasSingleTableMultitenant() ? getDescriptor().getSingleTableMultitenantFields() : null;
for (String contextProperty : referenceTenantFields.keySet()) {
List<DatabaseField> referenceFields = referenceTenantFields.get(contextProperty);
for (DatabaseField referenceField : referenceFields) {
// Only if it is a primary key field, otherwise we don't
// care about it.
if (referenceField.isPrimaryKey()) {
JoinColumnMetadata jcm = new JoinColumnMetadata();
// This join column must be read only.
jcm.setInsertable(false);
jcm.setUpdatable(false);
// If we have a related context property, look up a
// field that matches from it.
if (tenantFields != null && tenantFields.containsKey(contextProperty)) {
// This is going to return a list just pick the first
// field (they populate the same value so doesn't really
// matter which one we pick.
jcm.setName(tenantFields.get(contextProperty).get(0).getName());
} else {
// We don't have a match, use the same name.
jcm.setName(referenceField.getName());
}
jcm.setReferencedColumnName(referenceField.getName());
jcm.setProject(referenceDescriptor.getProject());
joinColumns.add(jcm);
}
}
}
}