Search in sources :

Example 1 with PropertyBasedMapping

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;
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) SelectableMapping(org.hibernate.metamodel.mapping.SelectableMapping) Table(org.hibernate.mapping.Table) VirtualModelPart(org.hibernate.metamodel.mapping.VirtualModelPart) BasicValuedModelPart(org.hibernate.metamodel.mapping.BasicValuedModelPart) ModelPart(org.hibernate.metamodel.mapping.ModelPart) EmbeddableValuedModelPart(org.hibernate.metamodel.mapping.EmbeddableValuedModelPart) BasicValuedModelPart(org.hibernate.metamodel.mapping.BasicValuedModelPart) ChainedPropertyAccessImpl(org.hibernate.property.access.internal.ChainedPropertyAccessImpl) PropertyAccess(org.hibernate.property.access.spi.PropertyAccess) PropertyBasedMapping(org.hibernate.metamodel.mapping.PropertyBasedMapping) OneToOne(org.hibernate.mapping.OneToOne) Selectable(org.hibernate.mapping.Selectable) ForeignKeyDescriptor(org.hibernate.metamodel.mapping.ForeignKeyDescriptor) EmbeddableValuedModelPart(org.hibernate.metamodel.mapping.EmbeddableValuedModelPart) EntityIdentifierMapping(org.hibernate.metamodel.mapping.EntityIdentifierMapping) NotYetImplementedFor6Exception(org.hibernate.NotYetImplementedFor6Exception)

Aggregations

NotYetImplementedFor6Exception (org.hibernate.NotYetImplementedFor6Exception)1 OneToOne (org.hibernate.mapping.OneToOne)1 Selectable (org.hibernate.mapping.Selectable)1 Table (org.hibernate.mapping.Table)1 BasicValuedModelPart (org.hibernate.metamodel.mapping.BasicValuedModelPart)1 EmbeddableValuedModelPart (org.hibernate.metamodel.mapping.EmbeddableValuedModelPart)1 EntityIdentifierMapping (org.hibernate.metamodel.mapping.EntityIdentifierMapping)1 ForeignKeyDescriptor (org.hibernate.metamodel.mapping.ForeignKeyDescriptor)1 ModelPart (org.hibernate.metamodel.mapping.ModelPart)1 PropertyBasedMapping (org.hibernate.metamodel.mapping.PropertyBasedMapping)1 SelectableMapping (org.hibernate.metamodel.mapping.SelectableMapping)1 VirtualModelPart (org.hibernate.metamodel.mapping.VirtualModelPart)1 EntityPersister (org.hibernate.persister.entity.EntityPersister)1 ChainedPropertyAccessImpl (org.hibernate.property.access.internal.ChainedPropertyAccessImpl)1 PropertyAccess (org.hibernate.property.access.spi.PropertyAccess)1