use of org.hibernate.metamodel.mapping.PropertyBasedMapping in project hibernate-orm by hibernate.
the class MappingModelCreationHelper method interpretToOneKeyDescriptor.
/**
* Tries to {@link ToOneAttributeMapping#setForeignKeyDescriptor}
* to the given attribute {@code attributeMapping}.
*
* @param attributeMapping The attribute for which we try to set the foreign key
* @param bootProperty The property
* @param bootValueMapping The value mapping
* @param inversePropertyAccess Access to the inverse property
* @param dialect Current dialect
* @param creationProcess Current creation process
* @return true if the foreign key is actually set
*/
public static boolean interpretToOneKeyDescriptor(ToOneAttributeMapping attributeMapping, Property bootProperty, ToOne bootValueMapping, PropertyAccess inversePropertyAccess, Dialect dialect, MappingModelCreationProcess creationProcess) {
if (attributeMapping.getForeignKeyDescriptor() != null) {
// already built/known
return true;
}
final String tableName = getTableIdentifierExpression(bootValueMapping.getTable(), creationProcess);
attributeMapping.setIdentifyingColumnsTableExpression(tableName);
final EntityPersister referencedEntityDescriptor = creationProcess.getEntityPersister(bootValueMapping.getReferencedEntityName());
String referencedPropertyName;
boolean swapDirection = false;
if (bootValueMapping instanceof OneToOne) {
OneToOne oneToOne = (OneToOne) bootValueMapping;
swapDirection = oneToOne.getForeignKeyType() == ForeignKeyDirection.TO_PARENT;
referencedPropertyName = oneToOne.getMappedByProperty();
if (referencedPropertyName == null) {
referencedPropertyName = oneToOne.getReferencedPropertyName();
}
} else {
referencedPropertyName = null;
}
if (referencedPropertyName != null) {
if (referencedPropertyName.indexOf(".") > 0) {
return interpretNestedToOneKeyDescriptor(referencedEntityDescriptor, referencedPropertyName, attributeMapping);
}
final ModelPart modelPart = referencedEntityDescriptor.findByPath(referencedPropertyName);
if (modelPart instanceof ToOneAttributeMapping) {
setReferencedAttributeForeignKeyDescriptor(attributeMapping, (ToOneAttributeMapping) modelPart, referencedEntityDescriptor, referencedPropertyName, dialect, creationProcess);
} else if (modelPart instanceof EmbeddableValuedModelPart) {
final EmbeddedForeignKeyDescriptor embeddedForeignKeyDescriptor = buildEmbeddableForeignKeyDescriptor((EmbeddableValuedModelPart) modelPart, bootValueMapping, attributeMapping.getDeclaringType(), attributeMapping.findContainingEntityMapping(), true, dialect, creationProcess);
attributeMapping.setForeignKeyDescriptor(embeddedForeignKeyDescriptor);
} else if (modelPart == null) {
throw new IllegalArgumentException("Unable to find attribute " + bootProperty.getPersistentClass().getEntityName() + " -> " + bootProperty.getName());
} else {
throw new NotYetImplementedFor6Exception("Support for foreign-keys based on `" + modelPart + "` not yet implemented: " + bootProperty.getPersistentClass().getEntityName() + " -> " + bootProperty.getName());
}
return true;
}
final ModelPart fkTarget;
if (bootValueMapping.isReferenceToPrimaryKey()) {
fkTarget = referencedEntityDescriptor.getIdentifierMapping();
} else {
fkTarget = referencedEntityDescriptor.findByPath(bootValueMapping.getReferencedPropertyName());
}
if (fkTarget instanceof BasicValuedModelPart) {
final BasicValuedModelPart simpleFkTarget = (BasicValuedModelPart) fkTarget;
final Iterator<Selectable> columnIterator = bootValueMapping.getColumnIterator();
final Table table = bootValueMapping.getTable();
final String tableExpression = getTableIdentifierExpression(table, creationProcess);
final BasicValuedModelPart declaringKeyPart;
final PropertyAccess declaringKeyPropertyAccess;
if (inversePropertyAccess == null) {
// So far, OneToOne mappings are only supported based on the owner's PK
if (bootValueMapping instanceof OneToOne) {
declaringKeyPart = simpleFkTarget;
final EntityIdentifierMapping identifierMapping = attributeMapping.findContainingEntityMapping().getIdentifierMapping();
declaringKeyPropertyAccess = ((PropertyBasedMapping) identifierMapping).getPropertyAccess();
} else {
declaringKeyPart = simpleFkTarget;
// declaringKeyPropertyAccess = ( (PropertyBasedMapping) declaringKeyPart ).getPropertyAccess();
declaringKeyPropertyAccess = new ChainedPropertyAccessImpl(attributeMapping.getPropertyAccess(), ((PropertyBasedMapping) declaringKeyPart).getPropertyAccess());
}
} else {
declaringKeyPart = simpleFkTarget;
declaringKeyPropertyAccess = new ChainedPropertyAccessImpl(inversePropertyAccess, ((PropertyBasedMapping) simpleFkTarget).getPropertyAccess());
}
final SelectableMapping keySelectableMapping;
if (columnIterator.hasNext()) {
keySelectableMapping = SelectableMappingImpl.from(tableExpression, columnIterator.next(), simpleFkTarget.getJdbcMapping(), dialect, creationProcess.getSqmFunctionRegistry());
} else {
// case of ToOne with @PrimaryKeyJoinColumn
keySelectableMapping = SelectableMappingImpl.from(tableExpression, table.getColumn(0), simpleFkTarget.getJdbcMapping(), dialect, creationProcess.getSqmFunctionRegistry());
}
final ForeignKeyDescriptor foreignKeyDescriptor = new SimpleForeignKeyDescriptor(attributeMapping.getDeclaringType(), declaringKeyPart, declaringKeyPropertyAccess, keySelectableMapping, simpleFkTarget, bootValueMapping.isReferenceToPrimaryKey(), bootValueMapping.isConstrained(), swapDirection);
attributeMapping.setForeignKeyDescriptor(foreignKeyDescriptor);
} else if (fkTarget instanceof EmbeddableValuedModelPart) {
final EmbeddedForeignKeyDescriptor embeddedForeignKeyDescriptor = buildEmbeddableForeignKeyDescriptor((EmbeddableValuedModelPart) fkTarget, bootValueMapping, attributeMapping.getDeclaringType(), attributeMapping.findContainingEntityMapping(), swapDirection, dialect, creationProcess);
attributeMapping.setForeignKeyDescriptor(embeddedForeignKeyDescriptor);
} else {
throw new NotYetImplementedFor6Exception("Support for " + fkTarget.getClass() + " foreign-keys not yet implemented: " + bootProperty.getPersistentClass().getEntityName() + " -> " + bootProperty.getName());
}
return true;
}
Aggregations