Search in sources :

Example 1 with StateArrayContributorMapping

use of org.hibernate.metamodel.mapping.StateArrayContributorMapping in project hibernate-orm by hibernate.

the class AbstractEntityPersister method selectFragment.

@Override
public String selectFragment(String alias, String suffix) {
    final QuerySpec rootQuerySpec = new QuerySpec(true);
    final String rootTableName = getRootTableName();
    final LoaderSqlAstCreationState sqlAstCreationState = new LoaderSqlAstCreationState(rootQuerySpec, new SqlAliasBaseManager(), new SimpleFromClauseAccessImpl(), LockOptions.NONE, (fetchParent, querySpec, creationState) -> {
        final List<Fetch> fetches = new ArrayList<>();
        fetchParent.getReferencedMappingContainer().visitFetchables(fetchable -> {
            // Ignore plural attributes
            if (fetchable instanceof PluralAttributeMapping) {
                return;
            }
            FetchTiming fetchTiming = fetchable.getMappedFetchOptions().getTiming();
            final boolean selectable;
            if (fetchable instanceof StateArrayContributorMapping) {
                final int propertyNumber = ((StateArrayContributorMapping) fetchable).getStateArrayPosition();
                final int tableNumber = getSubclassPropertyTableNumber(propertyNumber);
                selectable = !isSubclassTableSequentialSelect(tableNumber) && propertySelectable[propertyNumber];
            } else {
                selectable = true;
            }
            if (fetchable instanceof BasicValuedModelPart) {
                // Ignore lazy basic columns
                if (fetchTiming == FetchTiming.DELAYED) {
                    return;
                }
            } else if (fetchable instanceof Association) {
                final Association association = (Association) fetchable;
                // Ignore the fetchable if the FK is on the other side
                if (association.getSideNature() == ForeignKeyDescriptor.Nature.TARGET) {
                    return;
                }
                // Ensure the FK comes from the root table
                if (!rootTableName.equals(association.getForeignKeyDescriptor().getKeyTable())) {
                    return;
                }
                fetchTiming = FetchTiming.DELAYED;
            }
            if (selectable) {
                final NavigablePath navigablePath = fetchParent.resolveNavigablePath(fetchable);
                final Fetch fetch = fetchParent.generateFetchableFetch(fetchable, navigablePath, fetchTiming, true, null, creationState);
                fetches.add(fetch);
            }
        }, null);
        return fetches;
    }, true, getFactory());
    final NavigablePath entityPath = new NavigablePath(getRootPathName());
    final TableGroup rootTableGroup = createRootTableGroup(true, entityPath, null, () -> p -> {
    }, new SqlAliasBaseConstant(alias), sqlAstCreationState.getSqlExpressionResolver(), sqlAstCreationState.getFromClauseAccess(), getFactory());
    rootQuerySpec.getFromClause().addRoot(rootTableGroup);
    sqlAstCreationState.getFromClauseAccess().registerTableGroup(entityPath, rootTableGroup);
    createDomainResult(entityPath, rootTableGroup, null, sqlAstCreationState);
    // Wrap expressions with aliases
    final SelectClause selectClause = rootQuerySpec.getSelectClause();
    final List<SqlSelection> sqlSelections = selectClause.getSqlSelections();
    int i = 0;
    for (String identifierAlias : identifierAliases) {
        sqlSelections.set(i, new SqlSelectionImpl(i, i + 1, new AliasedExpression(sqlSelections.get(i).getExpression(), identifierAlias + suffix)));
        i++;
    }
    if (entityMetamodel.hasSubclasses()) {
        sqlSelections.set(i, new SqlSelectionImpl(i, i + 1, new AliasedExpression(sqlSelections.get(i).getExpression(), getDiscriminatorAlias() + suffix)));
        i++;
    }
    if (hasRowId()) {
        sqlSelections.set(i, new SqlSelectionImpl(i, i + 1, new AliasedExpression(sqlSelections.get(i).getExpression(), ROWID_ALIAS + suffix)));
        i++;
    }
    final String[] columnAliases = getSubclassColumnAliasClosure();
    final String[] formulaAliases = getSubclassFormulaAliasClosure();
    int columnIndex = 0;
    int formulaIndex = 0;
    for (; i < sqlSelections.size(); i++) {
        final SqlSelection sqlSelection = sqlSelections.get(i);
        final ColumnReference columnReference = (ColumnReference) sqlSelection.getExpression();
        final String selectAlias;
        if (!columnReference.isColumnExpressionFormula()) {
            // Skip over columns that are not selectable like in the fetch generation
            while (!subclassColumnSelectableClosure[columnIndex]) {
                columnIndex++;
            }
            selectAlias = columnAliases[columnIndex++] + suffix;
        } else {
            selectAlias = formulaAliases[formulaIndex++] + suffix;
        }
        sqlSelections.set(i, new SqlSelectionImpl(sqlSelection.getValuesArrayPosition(), sqlSelection.getJdbcResultSetIndex(), new AliasedExpression(sqlSelection.getExpression(), selectAlias)));
    }
    final String sql = getFactory().getJdbcServices().getDialect().getSqlAstTranslatorFactory().buildSelectTranslator(getFactory(), new SelectStatement(rootQuerySpec)).translate(null, QueryOptions.NONE).getSql();
    final int fromIndex = sql.lastIndexOf(" from");
    final String expression;
    if (fromIndex != -1) {
        expression = sql.substring("select ".length(), fromIndex);
    } else {
        expression = sql.substring("select ".length());
    }
    return expression;
}
Also used : SelectClause(org.hibernate.sql.ast.tree.select.SelectClause) NavigablePath(org.hibernate.query.spi.NavigablePath) ArrayList(java.util.ArrayList) PluralAttributeMapping(org.hibernate.metamodel.mapping.PluralAttributeMapping) SqlAliasBaseManager(org.hibernate.sql.ast.spi.SqlAliasBaseManager) SqlAliasBaseConstant(org.hibernate.sql.ast.spi.SqlAliasBaseConstant) SqlSelection(org.hibernate.sql.ast.spi.SqlSelection) AliasedExpression(org.hibernate.sql.ast.tree.expression.AliasedExpression) Fetch(org.hibernate.sql.results.graph.Fetch) SelectStatement(org.hibernate.sql.ast.tree.select.SelectStatement) Association(org.hibernate.metamodel.mapping.Association) StandardTableGroup(org.hibernate.sql.ast.tree.from.StandardTableGroup) TableGroup(org.hibernate.sql.ast.tree.from.TableGroup) BasicValuedModelPart(org.hibernate.metamodel.mapping.BasicValuedModelPart) SimpleFromClauseAccessImpl(org.hibernate.sql.ast.spi.SimpleFromClauseAccessImpl) StateArrayContributorMapping(org.hibernate.metamodel.mapping.StateArrayContributorMapping) LoaderSqlAstCreationState(org.hibernate.loader.ast.internal.LoaderSqlAstCreationState) FetchTiming(org.hibernate.engine.FetchTiming) SqlSelectionImpl(org.hibernate.sql.results.internal.SqlSelectionImpl) QuerySpec(org.hibernate.sql.ast.tree.select.QuerySpec) ColumnReference(org.hibernate.sql.ast.tree.expression.ColumnReference)

Example 2 with StateArrayContributorMapping

use of org.hibernate.metamodel.mapping.StateArrayContributorMapping in project hibernate-orm by hibernate.

the class AbstractEntityPersister method resolveDirtyAttributeIndexes.

@Override
public int[] resolveDirtyAttributeIndexes(final Object[] currentState, final Object[] previousState, final String[] attributeNames, final SessionImplementor session) {
    final BitSet mutablePropertiesIndexes = entityMetamodel.getMutablePropertiesIndexes();
    final int estimatedSize = attributeNames == null ? 0 : attributeNames.length + mutablePropertiesIndexes.cardinality();
    final List<Integer> fields = new ArrayList<>(estimatedSize);
    if (estimatedSize == 0) {
        return ArrayHelper.EMPTY_INT_ARRAY;
    }
    if (!mutablePropertiesIndexes.isEmpty()) {
        // We have to check the state for "mutable" properties as dirty tracking isn't aware of mutable types
        final Type[] propertyTypes = entityMetamodel.getPropertyTypes();
        final boolean[] propertyCheckability = entityMetamodel.getPropertyCheckability();
        mutablePropertiesIndexes.stream().forEach(i -> {
            // This is kindly borrowed from org.hibernate.type.TypeHelper.findDirty
            final boolean dirty = currentState[i] != LazyPropertyInitializer.UNFETCHED_PROPERTY && // Consider mutable properties as dirty if we don't have a previous state
            (previousState == null || previousState[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY || (propertyCheckability[i] && propertyTypes[i].isDirty(previousState[i], currentState[i], propertyColumnUpdateable[i], session)));
            if (dirty) {
                fields.add(i);
            }
        });
    }
    if (attributeNames.length != 0) {
        final boolean[] propertyUpdateability = entityMetamodel.getPropertyUpdateability();
        // Sort attribute names so that we can traverse mappings efficiently
        Arrays.sort(attributeNames);
        int index = 0;
        for (final AttributeMapping attributeMapping : attributeMappings) {
            final String attributeName = attributeMapping.getAttributeName();
            final int nameLength = attributeName.length();
            final String currentAttributeName = attributeNames[index];
            int position = ((StateArrayContributorMapping) attributeMapping).getStateArrayPosition();
            if (currentAttributeName.startsWith(attributeName) && ((currentAttributeName.length() == nameLength || currentAttributeName.charAt(nameLength) == '.'))) {
                if (propertyUpdateability[position] && !fields.contains(position)) {
                    fields.add(position);
                }
                index++;
                if (index < attributeNames.length) {
                    // Skip duplicates
                    do {
                        if (attributeNames[index].equals(attributeName)) {
                            index++;
                        } else {
                            break;
                        }
                    } while (index < attributeNames.length);
                } else {
                    break;
                }
            }
        }
    }
    return ArrayHelper.toIntArray(fields);
}
Also used : StateArrayContributorMapping(org.hibernate.metamodel.mapping.StateArrayContributorMapping) BasicType(org.hibernate.type.BasicType) EntityMappingType(org.hibernate.metamodel.mapping.EntityMappingType) InFlightEntityMappingType(org.hibernate.metamodel.mapping.internal.InFlightEntityMappingType) AssociationType(org.hibernate.type.AssociationType) AnyType(org.hibernate.type.AnyType) CompositeType(org.hibernate.type.CompositeType) ManagedMappingType(org.hibernate.metamodel.mapping.ManagedMappingType) JavaType(org.hibernate.type.descriptor.java.JavaType) CollectionType(org.hibernate.type.CollectionType) EntityType(org.hibernate.type.EntityType) Type(org.hibernate.type.Type) PluralAttributeMapping(org.hibernate.metamodel.mapping.PluralAttributeMapping) EmbeddedAttributeMapping(org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping) DiscriminatedAssociationAttributeMapping(org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationAttributeMapping) ToOneAttributeMapping(org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping) SingularAttributeMapping(org.hibernate.metamodel.mapping.SingularAttributeMapping) AttributeMapping(org.hibernate.metamodel.mapping.AttributeMapping) BitSet(java.util.BitSet) ArrayList(java.util.ArrayList)

Example 3 with StateArrayContributorMapping

use of org.hibernate.metamodel.mapping.StateArrayContributorMapping in project hibernate-orm by hibernate.

the class AbstractEntityPersister method setPropertyValues.

@Override
public void setPropertyValues(Object object, Object[] values) {
    if (accessOptimizer != null) {
        accessOptimizer.setPropertyValues(object, values);
    } else {
        if (hasSubclasses()) {
            visitAttributeMappings(attribute -> {
                final int stateArrayPosition = ((StateArrayContributorMapping) attribute).getStateArrayPosition();
                final Object value = values[stateArrayPosition];
                if (value != UNFETCHED_PROPERTY) {
                    final Setter setter = attribute.getPropertyAccess().getSetter();
                    setter.set(object, value);
                }
            });
        } else {
            visitFetchables(fetchable -> {
                final AttributeMapping attribute = (AttributeMapping) fetchable;
                final int stateArrayPosition = ((StateArrayContributorMapping) attribute).getStateArrayPosition();
                final Object value = values[stateArrayPosition];
                if (value != UNFETCHED_PROPERTY) {
                    final Setter setter = attribute.getPropertyAccess().getSetter();
                    setter.set(object, value);
                }
            }, null);
        }
    }
}
Also used : StateArrayContributorMapping(org.hibernate.metamodel.mapping.StateArrayContributorMapping) PluralAttributeMapping(org.hibernate.metamodel.mapping.PluralAttributeMapping) EmbeddedAttributeMapping(org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping) DiscriminatedAssociationAttributeMapping(org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationAttributeMapping) ToOneAttributeMapping(org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping) SingularAttributeMapping(org.hibernate.metamodel.mapping.SingularAttributeMapping) AttributeMapping(org.hibernate.metamodel.mapping.AttributeMapping) Setter(org.hibernate.property.access.spi.Setter)

Aggregations

PluralAttributeMapping (org.hibernate.metamodel.mapping.PluralAttributeMapping)3 StateArrayContributorMapping (org.hibernate.metamodel.mapping.StateArrayContributorMapping)3 ArrayList (java.util.ArrayList)2 AttributeMapping (org.hibernate.metamodel.mapping.AttributeMapping)2 SingularAttributeMapping (org.hibernate.metamodel.mapping.SingularAttributeMapping)2 DiscriminatedAssociationAttributeMapping (org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationAttributeMapping)2 EmbeddedAttributeMapping (org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping)2 ToOneAttributeMapping (org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping)2 BitSet (java.util.BitSet)1 FetchTiming (org.hibernate.engine.FetchTiming)1 LoaderSqlAstCreationState (org.hibernate.loader.ast.internal.LoaderSqlAstCreationState)1 Association (org.hibernate.metamodel.mapping.Association)1 BasicValuedModelPart (org.hibernate.metamodel.mapping.BasicValuedModelPart)1 EntityMappingType (org.hibernate.metamodel.mapping.EntityMappingType)1 ManagedMappingType (org.hibernate.metamodel.mapping.ManagedMappingType)1 InFlightEntityMappingType (org.hibernate.metamodel.mapping.internal.InFlightEntityMappingType)1 Setter (org.hibernate.property.access.spi.Setter)1 NavigablePath (org.hibernate.query.spi.NavigablePath)1 SimpleFromClauseAccessImpl (org.hibernate.sql.ast.spi.SimpleFromClauseAccessImpl)1 SqlAliasBaseConstant (org.hibernate.sql.ast.spi.SqlAliasBaseConstant)1