There is another workaround to this problem.
You can use an Eclipselink MetadataSource to override at runtime the annotations in the entity class and to pretend that you use a dedicated database per tenant, for example:
MultitenantMetadata md = new MultitenantMetadata();
md.setIncludeCriteria(false);
md.setType(MultitenantType.TABLE_PER_TENANT.name());
TenantTableDiscriminatorMetadata td = new TenantTableDiscriminatorMetadata();
td.setType(TenantTableDiscriminatorType.SCHEMA.toString());
td.setContextProperty(DISCRIMINATOR_SCHEMA_PROPERTY);
md.setTenantTableDiscriminator(td);
entityAccessor.setMultitenant(md);
The above will make Eclipselink happy from a multi-tenancy point of view, but your tables may still have the discriminator column if your annotations specify that multi-tenancy is achieved using a discriminator column.
To remove the discriminator column you can use a SessionCustomizer that manipulates the EclipseLink representation of the entities before the EMF is created in order to:
- Remove the discriminator column
- Change indices and foreign keys to remove any reference to the discriminator column.
In this way the database tables and the DDLs will no more include the discriminator column.
Set<String> discriminatorColumnNames = getDiscriminatorColumns(descriptor);
for (DatabaseTable databaseTable : descriptor.getTables()) {
List<IndexDefinition> indexDefinitions = databaseTable.getIndexes();
for (Iterator<IndexDefinition> definitionIt = indexDefinitions.iterator(); definitionIt.hasNext();) {
IndexDefinition indexDefinition = definitionIt.next();
// remove qualifier from index to prevent a syntax error in DDL
indexDefinition.setQualifier("");
for (Iterator<String> fieldNameIt = indexDefinition.getFields().iterator(); fieldNameIt.hasNext();) {
if (discriminatorColumnNames.contains(fieldNameIt.next().toUpperCase())) {
fieldNameIt.remove();
}
}
if (indexDefinition.getFields().isEmpty()) {
definitionIt.remove();
}
}
Map<String, List<List<String>>> uniqueConstraints = databaseTable.getUniqueConstraints();
for (Entry<String, List<List<String>>> uc : uniqueConstraints.entrySet()) {
List<List<String>> strings = uc.getValue();
for (List<String> list : strings) {
String found = null;
for (String string : list) {
if (discriminatorColumnNames.contains(string.toUpperCase())) {
found = string;
break;
}
}
if (found != null) {
list.remove(found);
}
}
}
}