use of org.hibernate.metamodel.mapping.EntityValuedModelPart in project hibernate-orm by hibernate.
the class DiscriminatorSqmPath method interpret.
@Override
public SqmPathInterpretation<?> interpret(SqlAstCreationState sqlAstCreationState, SemanticQueryWalker sqmWalker, boolean jpaQueryComplianceEnabled) {
assert entityDescriptor.hasSubclasses();
final TableGroup tableGroup = sqlAstCreationState.getFromClauseAccess().getTableGroup(getLhs().getNavigablePath());
final ModelPartContainer modelPart = tableGroup.getModelPart();
final EntityMappingType entityMapping;
if (modelPart instanceof EntityValuedModelPart) {
entityMapping = ((EntityValuedModelPart) modelPart).getEntityMappingType();
} else {
entityMapping = (EntityMappingType) ((PluralAttributeMapping) modelPart).getElementDescriptor().getPartMappingType();
}
return new DiscriminatorPathInterpretation(getNavigablePath(), entityMapping, tableGroup, sqlAstCreationState);
}
use of org.hibernate.metamodel.mapping.EntityValuedModelPart in project hibernate-orm by hibernate.
the class EntityValuedPathInterpretation method from.
public static <T> EntityValuedPathInterpretation<T> from(SqmEntityValuedSimplePath<T> sqmPath, MappingModelExpressible<?> inferredMapping, SqmToSqlAstConverter sqlAstCreationState) {
final TableGroup tableGroup = sqlAstCreationState.getFromClauseAccess().findTableGroup(sqmPath.getLhs().getNavigablePath());
final EntityValuedModelPart pathMapping = (EntityValuedModelPart) sqlAstCreationState.getFromClauseAccess().findTableGroup(sqmPath.getLhs().getNavigablePath()).getModelPart().findSubPart(sqmPath.getReferencedPathSource().getPathName(), null);
final EntityValuedModelPart mapping;
if (inferredMapping instanceof EntityAssociationMapping) {
final EntityAssociationMapping inferredAssociation = (EntityAssociationMapping) inferredMapping;
if (pathMapping instanceof EntityAssociationMapping && inferredMapping != pathMapping) {
// In here, the inferred mapping and the actual path mapping are association mappings,
// but for different associations, so we have to check if both associations point to the same target
final EntityAssociationMapping pathAssociation = (EntityAssociationMapping) pathMapping;
final ModelPart pathTargetPart = pathAssociation.getForeignKeyDescriptor().getPart(pathAssociation.getSideNature().inverse());
final ModelPart inferredTargetPart = inferredAssociation.getForeignKeyDescriptor().getPart(inferredAssociation.getSideNature().inverse());
// which will render the FK of the path association
if (pathTargetPart == inferredTargetPart) {
mapping = pathMapping;
} else {
// Otherwise, we need to use the entity mapping type to force rendering the PK
// for e.g. `a.assoc1 = a.assoc2` when both associations have different target join columns
mapping = pathMapping.getEntityMappingType();
}
} else {
// This is the case when the inferred mapping is an association, but the path mapping is not,
// or the path mapping and the inferred mapping are for the same association
mapping = (EntityValuedModelPart) inferredMapping;
}
} else {
mapping = pathMapping;
}
final ModelPart resultModelPart;
if (mapping instanceof EntityAssociationMapping) {
final EntityAssociationMapping associationMapping = (EntityAssociationMapping) mapping;
final ModelPart keyTargetMatchPart = associationMapping.getKeyTargetMatchPart();
if (keyTargetMatchPart instanceof ToOneAttributeMapping) {
resultModelPart = ((ToOneAttributeMapping) keyTargetMatchPart).getKeyTargetMatchPart();
} else {
resultModelPart = keyTargetMatchPart;
}
} else {
resultModelPart = mapping.getEntityMappingType().getIdentifierMapping();
}
return from(sqmPath.getNavigablePath(), tableGroup, resultModelPart, mapping, mapping, sqlAstCreationState);
}
use of org.hibernate.metamodel.mapping.EntityValuedModelPart in project hibernate-orm by hibernate.
the class EntityValuedPathInterpretation method from.
public static <T> EntityValuedPathInterpretation<T> from(NavigablePath navigablePath, TableGroup tableGroup, ModelPart resultModelPart, EntityValuedModelPart mapping, EntityValuedModelPart treatedMapping, SqmToSqlAstConverter sqlAstCreationState) {
final SqlExpressionResolver sqlExprResolver = sqlAstCreationState.getSqlExpressionResolver();
final SessionFactoryImplementor sessionFactory = sqlAstCreationState.getCreationContext().getSessionFactory();
final Expression sqlExpression;
if (resultModelPart == null) {
final EntityMappingType entityMappingType = mapping.getEntityMappingType();
final EntityIdentifierMapping identifierMapping = entityMappingType.getIdentifierMapping();
final EntityDiscriminatorMapping discriminatorMapping = entityMappingType.getDiscriminatorMapping();
final List<Expression> expressions = new ArrayList<>(entityMappingType.getJdbcTypeCount() + identifierMapping.getJdbcTypeCount() + (discriminatorMapping == null ? 0 : 1));
final TableGroup parentTableGroup = tableGroup;
final SelectableConsumer selectableConsumer = (selectionIndex, selectableMapping) -> {
final TableReference tableReference = parentTableGroup.resolveTableReference(navigablePath, selectableMapping.getContainingTableExpression(), false);
expressions.add(sqlExprResolver.resolveSqlExpression(createColumnReferenceKey(tableReference, selectableMapping.getSelectionExpression()), processingState -> new ColumnReference(tableReference, selectableMapping, sessionFactory)));
};
identifierMapping.forEachSelectable(selectableConsumer);
if (discriminatorMapping != null) {
discriminatorMapping.forEachSelectable(selectableConsumer);
}
entityMappingType.forEachSelectable(selectableConsumer);
sqlExpression = new SqlTuple(expressions, entityMappingType);
} else {
if (resultModelPart instanceof BasicValuedModelPart) {
final BasicValuedModelPart basicValuedModelPart = (BasicValuedModelPart) resultModelPart;
final TableReference tableReference = tableGroup.resolveTableReference(navigablePath, basicValuedModelPart.getContainingTableExpression());
sqlExpression = sqlExprResolver.resolveSqlExpression(createColumnReferenceKey(tableReference, basicValuedModelPart.getSelectionExpression()), processingState -> new ColumnReference(tableReference, basicValuedModelPart, sessionFactory));
} else {
final List<Expression> expressions = new ArrayList<>(resultModelPart.getJdbcTypeCount());
resultModelPart.forEachSelectable((selectionIndex, selectableMapping) -> {
final TableReference tableReference = tableGroup.resolveTableReference(navigablePath, selectableMapping.getContainingTableExpression());
expressions.add(sqlExprResolver.resolveSqlExpression(createColumnReferenceKey(tableReference, selectableMapping.getSelectionExpression()), processingState -> new ColumnReference(tableReference, selectableMapping, sessionFactory)));
});
sqlExpression = new SqlTuple(expressions, resultModelPart);
}
}
return new EntityValuedPathInterpretation<>(sqlExpression, navigablePath, tableGroup, treatedMapping);
}
use of org.hibernate.metamodel.mapping.EntityValuedModelPart in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitTableGroup.
private Expression visitTableGroup(TableGroup tableGroup, SqmFrom<?, ?> path) {
final ModelPartContainer modelPart;
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
// For plain SqmFrom node uses, prefer the mapping type from the context if possible
if (!(inferredValueMapping instanceof ModelPartContainer)) {
modelPart = tableGroup.getModelPart();
} else {
modelPart = (ModelPartContainer) inferredValueMapping;
}
final ModelPart resultModelPart;
final ModelPart interpretationModelPart;
final TableGroup parentGroupToUse;
if (modelPart instanceof ToOneAttributeMapping) {
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) modelPart;
final ModelPart targetPart = toOneAttributeMapping.getForeignKeyDescriptor().getPart(toOneAttributeMapping.getSideNature().inverse());
if (tableGroup.getModelPart().getPartMappingType() == modelPart.getPartMappingType()) {
resultModelPart = targetPart;
} else {
// If the table group is for a different mapping type i.e. an inheritance subtype,
// lookup the target part on that mapping type
resultModelPart = tableGroup.getModelPart().findSubPart(targetPart.getPartName(), null);
}
interpretationModelPart = modelPart;
parentGroupToUse = null;
} else if (modelPart instanceof PluralAttributeMapping) {
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) modelPart;
final CollectionPart elementDescriptor = pluralAttributeMapping.getElementDescriptor();
if (elementDescriptor instanceof EntityCollectionPart) {
// Usually, we need to resolve to the PK for visitTableGroup
final EntityCollectionPart collectionPart = (EntityCollectionPart) elementDescriptor;
final ModelPart collectionTargetPart = collectionPart.getForeignKeyDescriptor().getPart(collectionPart.getSideNature().inverse());
final EntityIdentifierMapping identifierMapping = collectionPart.getEntityMappingType().getIdentifierMapping();
// If the FK points to the PK, we can use the FK part though, if this is not a root
if (collectionTargetPart == identifierMapping && !(path instanceof SqmRoot<?>)) {
resultModelPart = collectionPart.getForeignKeyDescriptor().getPart(collectionPart.getSideNature());
} else {
resultModelPart = identifierMapping;
}
} else {
resultModelPart = elementDescriptor;
}
interpretationModelPart = elementDescriptor;
parentGroupToUse = null;
} else if (modelPart instanceof EntityCollectionPart) {
// Usually, we need to resolve to the PK for visitTableGroup
final EntityCollectionPart collectionPart = (EntityCollectionPart) modelPart;
final ModelPart collectionTargetPart = collectionPart.getForeignKeyDescriptor().getPart(collectionPart.getSideNature().inverse());
final EntityIdentifierMapping identifierMapping = collectionPart.getEntityMappingType().getIdentifierMapping();
// If the FK points to the PK, we can use the FK part though, if this is not a root
if (collectionTargetPart == identifierMapping && !(path instanceof SqmRoot<?>)) {
resultModelPart = collectionPart.getForeignKeyDescriptor().getPart(collectionPart.getSideNature());
} else {
resultModelPart = identifierMapping;
}
interpretationModelPart = modelPart;
parentGroupToUse = findTableGroup(tableGroup.getNavigablePath().getParent());
} else if (modelPart instanceof EntityMappingType) {
resultModelPart = ((EntityMappingType) modelPart).getIdentifierMapping();
interpretationModelPart = modelPart;
// todo: I think this will always be null anyways because EntityMappingType will only be the model part
// of a TableGroup if that is a root TableGroup, so check if we can just switch to null
parentGroupToUse = findTableGroup(tableGroup.getNavigablePath().getParent());
} else {
resultModelPart = modelPart;
interpretationModelPart = modelPart;
parentGroupToUse = null;
}
final NavigablePath navigablePath;
if (interpretationModelPart == modelPart) {
navigablePath = tableGroup.getNavigablePath();
} else {
navigablePath = tableGroup.getNavigablePath().append(interpretationModelPart.getPartName());
}
final Expression result;
if (interpretationModelPart instanceof EntityValuedModelPart) {
final boolean expandToAllColumns;
if (currentClauseStack.getCurrent() == Clause.GROUP) {
// When the table group is known to be fetched i.e. a fetch join
// but also when the from clause is part of the select clause
// we need to expand to all columns, as we also expand this to all columns in the select clause
expandToAllColumns = tableGroup.isFetched() || selectClauseContains(path);
} else {
expandToAllColumns = false;
}
final EntityValuedModelPart mapping = (EntityValuedModelPart) interpretationModelPart;
EntityMappingType mappingType;
if (path instanceof SqmTreatedPath) {
mappingType = creationContext.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel().findEntityDescriptor(((SqmTreatedPath<?, ?>) path).getTreatTarget().getHibernateEntityName());
} else {
mappingType = mapping.getEntityMappingType();
}
result = EntityValuedPathInterpretation.from(navigablePath, parentGroupToUse == null ? tableGroup : parentGroupToUse, expandToAllColumns ? null : resultModelPart, (EntityValuedModelPart) interpretationModelPart, mappingType, this);
} else if (interpretationModelPart instanceof EmbeddableValuedModelPart) {
final EmbeddableValuedModelPart mapping = (EmbeddableValuedModelPart) resultModelPart;
result = new EmbeddableValuedPathInterpretation<>(mapping.toSqlExpression(tableGroup, currentClauseStack.getCurrent(), this, getSqlAstCreationState()), navigablePath, (EmbeddableValuedModelPart) interpretationModelPart, tableGroup);
} else {
assert interpretationModelPart instanceof BasicValuedModelPart;
final BasicValuedModelPart mapping = (BasicValuedModelPart) resultModelPart;
final TableReference tableReference = tableGroup.resolveTableReference(navigablePath.append(resultModelPart.getPartName()), mapping.getContainingTableExpression());
final Expression expression = getSqlExpressionResolver().resolveSqlExpression(SqlExpressionResolver.createColumnReferenceKey(tableReference, mapping.getSelectionExpression()), sacs -> new ColumnReference(tableReference.getIdentificationVariable(), mapping, getCreationContext().getSessionFactory()));
final ColumnReference columnReference;
if (expression instanceof ColumnReference) {
columnReference = (ColumnReference) expression;
} else if (expression instanceof SqlSelectionExpression) {
final Expression selectedExpression = ((SqlSelectionExpression) expression).getSelection().getExpression();
assert selectedExpression instanceof ColumnReference;
columnReference = (ColumnReference) selectedExpression;
} else {
throw new UnsupportedOperationException("Unsupported basic-valued path expression : " + expression);
}
result = new BasicValuedPathInterpretation<>(columnReference, navigablePath, (BasicValuedModelPart) interpretationModelPart, tableGroup);
}
return withTreatRestriction(result, path);
}
use of org.hibernate.metamodel.mapping.EntityValuedModelPart in project hibernate-orm by hibernate.
the class TableGroup method applySqlSelections.
@Override
default void applySqlSelections(DomainResultCreationState creationState) {
final ModelPartContainer modelPart = getModelPart();
final ModelPart modelPartToApply;
if (modelPart instanceof EntityValuedModelPart) {
modelPartToApply = ((EntityValuedModelPart) modelPart).getEntityMappingType();
} else {
modelPartToApply = modelPart;
}
modelPartToApply.applySqlSelections(getNavigablePath(), creationState.getSqlAstCreationState().getFromClauseAccess().findTableGroup(getNavigablePath()), creationState);
}
Aggregations