Search in sources :

Example 1 with SortableValue

use of org.hibernate.mapping.SortableValue in project hibernate-orm by hibernate.

the class MappingModelCreationHelper method getPropertyOrder.

private static int[] getPropertyOrder(Value bootValueMapping, MappingModelCreationProcess creationProcess) {
    final ComponentType componentType;
    final boolean sorted;
    if (bootValueMapping instanceof Collection) {
        final Collection collectionBootValueMapping = (Collection) bootValueMapping;
        componentType = (ComponentType) collectionBootValueMapping.getKey().getType();
        assert ((SortableValue) collectionBootValueMapping.getKey()).isSorted();
        sorted = ((SortableValue) collectionBootValueMapping.getKey()).isSorted();
    } else {
        final EntityType entityType = (EntityType) bootValueMapping.getType();
        final Type identifierOrUniqueKeyType = entityType.getIdentifierOrUniqueKeyType(creationProcess.getCreationContext().getSessionFactory());
        if (identifierOrUniqueKeyType instanceof ComponentType) {
            componentType = (ComponentType) identifierOrUniqueKeyType;
            if (bootValueMapping instanceof ToOne) {
                assert ((ToOne) bootValueMapping).isSorted();
                sorted = ((ToOne) bootValueMapping).isSorted();
            } else {
                // Assume one-to-many is sorted, because it always uses the primary key value
                sorted = true;
            }
        } else {
            // This happens when we have a one-to-many with a mapped-by associations that has a basic FK
            return new int[] { 0 };
        }
    }
    // Consider the reordering if available
    if (!sorted && componentType.getOriginalPropertyOrder() != null) {
        return componentType.getOriginalPropertyOrder();
    } else // A value that came from the annotation model is already sorted appropriately
    // so we use an "identity mapping"
    {
        final int columnSpan = componentType.getColumnSpan(creationProcess.getCreationContext().getBootModel());
        final int[] propertyReordering = new int[columnSpan];
        for (int i = 0; i < columnSpan; i++) {
            propertyReordering[i] = i;
        }
        return propertyReordering;
    }
}
Also used : EntityType(org.hibernate.type.EntityType) ComponentType(org.hibernate.type.ComponentType) BasicType(org.hibernate.type.BasicType) EntityMappingType(org.hibernate.metamodel.mapping.EntityMappingType) CollectionMappingType(org.hibernate.metamodel.mapping.CollectionMappingType) JavaType(org.hibernate.type.descriptor.java.JavaType) EntityType(org.hibernate.type.EntityType) ComponentType(org.hibernate.type.ComponentType) CompositeType(org.hibernate.type.CompositeType) ManagedMappingType(org.hibernate.metamodel.mapping.ManagedMappingType) EmbeddableMappingType(org.hibernate.metamodel.mapping.EmbeddableMappingType) AssociationType(org.hibernate.type.AssociationType) Type(org.hibernate.type.Type) ToOne(org.hibernate.mapping.ToOne) OneToOne(org.hibernate.mapping.OneToOne) ManyToOne(org.hibernate.mapping.ManyToOne) Collection(org.hibernate.mapping.Collection) IndexedCollection(org.hibernate.mapping.IndexedCollection) SQLLoadableCollection(org.hibernate.persister.collection.SQLLoadableCollection) QueryableCollection(org.hibernate.persister.collection.QueryableCollection) SortableValue(org.hibernate.mapping.SortableValue)

Example 2 with SortableValue

use of org.hibernate.mapping.SortableValue in project hibernate-orm by hibernate.

the class ModelBinder method bindRootEntity.

private void bindRootEntity(EntityHierarchySourceImpl hierarchySource, RootClass rootEntityDescriptor) {
    final MappingDocument mappingDocument = hierarchySource.getRoot().sourceMappingDocument();
    bindBasicEntityValues(mappingDocument, hierarchySource.getRoot(), rootEntityDescriptor);
    final Table primaryTable = bindEntityTableSpecification(mappingDocument, hierarchySource.getRoot().getPrimaryTable(), null, hierarchySource.getRoot(), rootEntityDescriptor);
    rootEntityDescriptor.setTable(primaryTable);
    if (log.isDebugEnabled()) {
        log.debugf("Mapping class: %s -> %s", rootEntityDescriptor.getEntityName(), primaryTable.getName());
    }
    rootEntityDescriptor.setOptimisticLockStyle(hierarchySource.getOptimisticLockStyle());
    rootEntityDescriptor.setMutable(hierarchySource.isMutable());
    rootEntityDescriptor.setWhere(hierarchySource.getWhere());
    rootEntityDescriptor.setExplicitPolymorphism(hierarchySource.isExplicitPolymorphism());
    bindEntityIdentifier(mappingDocument, hierarchySource, rootEntityDescriptor);
    if (hierarchySource.getVersionAttributeSource() != null) {
        bindEntityVersion(mappingDocument, hierarchySource, rootEntityDescriptor);
    }
    if (hierarchySource.getDiscriminatorSource() != null) {
        bindEntityDiscriminator(mappingDocument, hierarchySource, rootEntityDescriptor);
    }
    applyCaching(mappingDocument, hierarchySource.getCaching(), rootEntityDescriptor);
    if (rootEntityDescriptor.getIdentifier() instanceof SortableValue) {
        ((SortableValue) rootEntityDescriptor.getIdentifier()).sortProperties();
    }
    // Primary key constraint
    rootEntityDescriptor.createPrimaryKey();
    bindAllEntityAttributes(mappingDocument, hierarchySource.getRoot(), rootEntityDescriptor);
    if (hierarchySource.getNaturalIdCaching() != null) {
        if (hierarchySource.getNaturalIdCaching().getRequested() == TruthValue.TRUE) {
            rootEntityDescriptor.setNaturalIdCacheRegionName(hierarchySource.getNaturalIdCaching().getRegion());
        }
    }
}
Also used : Table(org.hibernate.mapping.Table) DenormalizedTable(org.hibernate.mapping.DenormalizedTable) SortableValue(org.hibernate.mapping.SortableValue)

Example 3 with SortableValue

use of org.hibernate.mapping.SortableValue in project hibernate-orm by hibernate.

the class TableBinder method bindFk.

public static void bindFk(PersistentClass referencedEntity, PersistentClass destinationEntity, AnnotatedJoinColumn[] columns, SimpleValue value, boolean unique, MetadataBuildingContext buildingContext) {
    PersistentClass associatedClass;
    if (destinationEntity != null) {
        // overridden destination
        associatedClass = destinationEntity;
    } else {
        associatedClass = columns[0].getPropertyHolder() == null ? null : columns[0].getPropertyHolder().getPersistentClass();
    }
    final String mappedByProperty = columns[0].getMappedBy();
    if (StringHelper.isNotEmpty(mappedByProperty)) {
        /*
			 * Get the columns of the mapped-by property
			 * copy them and link the copy to the actual value
			 */
        LOG.debugf("Retrieving property %s.%s", associatedClass.getEntityName(), mappedByProperty);
        final Property property = associatedClass.getRecursiveProperty(columns[0].getMappedBy());
        List<Column> mappedByColumns;
        if (property.getValue() instanceof Collection) {
            Collection collection = ((Collection) property.getValue());
            Value element = collection.getElement();
            if (element == null) {
                throw new AnnotationException("Illegal use of mappedBy on both sides of the relationship: " + associatedClass.getEntityName() + "." + mappedByProperty);
            }
            mappedByColumns = element.getColumns();
        } else {
            mappedByColumns = property.getValue().getColumns();
        }
        for (Column column : mappedByColumns) {
            columns[0].overrideFromReferencedColumnIfNecessary(column);
            columns[0].linkValueUsingAColumnCopy(column, value);
        }
    } else if (columns[0].isImplicit()) {
        /*
			 * if columns are implicit, then create the columns based on the
			 * referenced entity id columns
			 */
        List<Column> idColumns = referencedEntity instanceof JoinedSubclass ? referencedEntity.getKey().getColumns() : referencedEntity.getIdentifier().getColumns();
        for (Column column : idColumns) {
            columns[0].linkValueUsingDefaultColumnNaming(column, referencedEntity, value);
            columns[0].overrideFromReferencedColumnIfNecessary(column);
        }
    } else {
        int fkEnum = AnnotatedJoinColumn.checkReferencedColumnsType(columns, referencedEntity, buildingContext);
        if (AnnotatedJoinColumn.NON_PK_REFERENCE == fkEnum) {
            String referencedPropertyName;
            if (value instanceof ToOne) {
                referencedPropertyName = ((ToOne) value).getReferencedPropertyName();
            } else if (value instanceof DependantValue) {
                String propertyName = columns[0].getPropertyName();
                if (propertyName != null) {
                    Collection collection = (Collection) referencedEntity.getRecursiveProperty(propertyName).getValue();
                    referencedPropertyName = collection.getReferencedPropertyName();
                } else {
                    throw new AnnotationException("SecondaryTable JoinColumn cannot reference a non primary key");
                }
            } else {
                throw new AssertionFailure("Do a property ref on an unexpected Value type: " + value.getClass().getName());
            }
            if (referencedPropertyName == null) {
                throw new AssertionFailure("No property ref found while expected");
            }
            Property synthProp = referencedEntity.getReferencedProperty(referencedPropertyName);
            if (synthProp == null) {
                throw new AssertionFailure("Cannot find synthProp: " + referencedEntity.getEntityName() + "." + referencedPropertyName);
            }
            linkJoinColumnWithValueOverridingNameIfImplicit(referencedEntity, synthProp.getValue(), columns, value);
            if (value instanceof SortableValue) {
                ((SortableValue) value).sortProperties();
            }
        } else {
            if (AnnotatedJoinColumn.NO_REFERENCE == fkEnum) {
                // implicit case, we hope PK and FK columns are in the same order
                if (columns.length != referencedEntity.getIdentifier().getColumnSpan()) {
                    throw new AnnotationException("A Foreign key referring " + referencedEntity.getEntityName() + " from " + associatedClass.getEntityName() + " has the wrong number of column. should be " + referencedEntity.getIdentifier().getColumnSpan());
                }
                linkJoinColumnWithValueOverridingNameIfImplicit(referencedEntity, referencedEntity.getIdentifier(), columns, value);
                if (value instanceof SortableValue) {
                    ((SortableValue) value).sortProperties();
                }
            } else {
                // Ensure the component is sorted so that we can simply set sorted to true on the to-one
                if (referencedEntity.getKey() instanceof Component) {
                    ((Component) referencedEntity.getKey()).sortProperties();
                }
                // explicit referencedColumnName
                List<Column> idColumns = referencedEntity.getKey().getColumns();
                // works cause the pk has to be on the primary table
                Table table = referencedEntity.getTable();
                if (idColumns.isEmpty()) {
                    LOG.debug("No column in the identifier!");
                }
                for (Column col : idColumns) {
                    boolean match = false;
                    // for each PK column, find the associated FK column.
                    Dialect dialect = buildingContext.getMetadataCollector().getDatabase().getJdbcEnvironment().getDialect();
                    final String colName = col.getQuotedName(dialect);
                    for (AnnotatedJoinColumn joinCol : columns) {
                        String referencedColumn = joinCol.getReferencedColumn();
                        referencedColumn = buildingContext.getMetadataCollector().getPhysicalColumnName(table, referencedColumn);
                        // In JPA 2 referencedColumnName is case-insensitive
                        if (referencedColumn.equalsIgnoreCase(colName)) {
                            // proper join column
                            if (joinCol.isNameDeferred()) {
                                joinCol.linkValueUsingDefaultColumnNaming(col, referencedEntity, value);
                            } else {
                                joinCol.linkWithValue(value);
                            }
                            joinCol.overrideFromReferencedColumnIfNecessary(col);
                            match = true;
                            break;
                        }
                    }
                    if (!match) {
                        throw new AnnotationException("Column name " + col.getName() + " of " + referencedEntity.getEntityName() + " not found in JoinColumns.referencedColumnName");
                    }
                }
                if (value instanceof ToOne) {
                    ((ToOne) value).setSorted(true);
                }
            }
        }
    }
    value.createForeignKey();
    if (unique) {
        value.createUniqueKey();
    }
}
Also used : AssertionFailure(org.hibernate.AssertionFailure) Table(org.hibernate.mapping.Table) DependantValue(org.hibernate.mapping.DependantValue) AnnotatedJoinColumn(org.hibernate.cfg.AnnotatedJoinColumn) Column(org.hibernate.mapping.Column) SortableValue(org.hibernate.mapping.SortableValue) SimpleValue(org.hibernate.mapping.SimpleValue) DependantValue(org.hibernate.mapping.DependantValue) Value(org.hibernate.mapping.Value) ToOne(org.hibernate.mapping.ToOne) Dialect(org.hibernate.dialect.Dialect) Collection(org.hibernate.mapping.Collection) AnnotationException(org.hibernate.AnnotationException) ArrayList(java.util.ArrayList) List(java.util.List) AnnotatedJoinColumn(org.hibernate.cfg.AnnotatedJoinColumn) JoinedSubclass(org.hibernate.mapping.JoinedSubclass) Component(org.hibernate.mapping.Component) Property(org.hibernate.mapping.Property) PersistentClass(org.hibernate.mapping.PersistentClass) SortableValue(org.hibernate.mapping.SortableValue)

Example 4 with SortableValue

use of org.hibernate.mapping.SortableValue in project hibernate-orm by hibernate.

the class OneToOneSecondPass method buildJoinFromMappedBySide.

/**
 * Builds the <code>Join</code> instance for the mapped by side of a <i>OneToOne</i> association using
 * a join table.
 * <p>
 * Note:<br/>
 * <ul>
 * <li>From the mappedBy side we should not create the PK nor the FK, this is handled from the other side.</li>
 * <li>This method is a dirty dupe of EntityBinder.bindSecondaryTable</li>.
 * </ul>
 * </p>
 */
private Join buildJoinFromMappedBySide(PersistentClass persistentClass, Property otherSideProperty, Join originalJoin) {
    Join join = new Join();
    join.setPersistentClass(persistentClass);
    // no check constraints available on joins
    join.setTable(originalJoin.getTable());
    join.setInverse(true);
    DependantValue key = new DependantValue(buildingContext, join.getTable(), persistentClass.getIdentifier());
    // TODO support @ForeignKey
    join.setKey(key);
    join.setSequentialSelect(false);
    // TODO support for inverse and optional
    // perhaps not quite per-spec, but a Good Thing anyway
    join.setOptional(true);
    key.setCascadeDeleteEnabled(false);
    for (Column column : otherSideProperty.getValue().getColumns()) {
        Column copy = new Column();
        copy.setLength(column.getLength());
        copy.setScale(column.getScale());
        copy.setValue(key);
        copy.setName(column.getQuotedName());
        copy.setNullable(column.isNullable());
        copy.setPrecision(column.getPrecision());
        copy.setUnique(column.isUnique());
        copy.setSqlType(column.getSqlType());
        copy.setCheckConstraint(column.getCheckConstraint());
        copy.setComment(column.getComment());
        copy.setDefaultValue(column.getDefaultValue());
        column.setGeneratedAs(column.getGeneratedAs());
        key.addColumn(copy);
    }
    if (otherSideProperty.getValue() instanceof SortableValue && !((SortableValue) otherSideProperty.getValue()).isSorted()) {
        key.sortProperties();
    }
    persistentClass.addJoin(join);
    return join;
}
Also used : DependantValue(org.hibernate.mapping.DependantValue) Column(org.hibernate.mapping.Column) JoinColumn(jakarta.persistence.JoinColumn) Join(org.hibernate.mapping.Join) SortableValue(org.hibernate.mapping.SortableValue)

Aggregations

SortableValue (org.hibernate.mapping.SortableValue)4 Collection (org.hibernate.mapping.Collection)2 Column (org.hibernate.mapping.Column)2 DependantValue (org.hibernate.mapping.DependantValue)2 Table (org.hibernate.mapping.Table)2 ToOne (org.hibernate.mapping.ToOne)2 JoinColumn (jakarta.persistence.JoinColumn)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 AnnotationException (org.hibernate.AnnotationException)1 AssertionFailure (org.hibernate.AssertionFailure)1 AnnotatedJoinColumn (org.hibernate.cfg.AnnotatedJoinColumn)1 Dialect (org.hibernate.dialect.Dialect)1 Component (org.hibernate.mapping.Component)1 DenormalizedTable (org.hibernate.mapping.DenormalizedTable)1 IndexedCollection (org.hibernate.mapping.IndexedCollection)1 Join (org.hibernate.mapping.Join)1 JoinedSubclass (org.hibernate.mapping.JoinedSubclass)1 ManyToOne (org.hibernate.mapping.ManyToOne)1 OneToOne (org.hibernate.mapping.OneToOne)1