use of org.hibernate.metamodel.mapping.ModelPartContainer in project hibernate-orm by hibernate.
the class ToOneAttributeMapping method createTableGroupJoin.
@Override
public TableGroupJoin createTableGroupJoin(NavigablePath navigablePath, TableGroup lhs, String explicitSourceAlias, SqlAstJoinType requestedJoinType, boolean fetched, boolean addsPredicate, SqlAliasBaseGenerator aliasBaseGenerator, SqlExpressionResolver sqlExpressionResolver, FromClauseAccess fromClauseAccess, SqlAstCreationContext creationContext) {
// This is vital for the map key property check that comes next
assert !(lhs instanceof PluralTableGroup);
TableGroup parentTableGroup = lhs;
ModelPartContainer parentContainer = lhs.getModelPart();
StringBuilder embeddablePathSb = null;
// Traverse up embeddable table groups until we find a table group for a collection part
while (!(parentContainer instanceof CollectionPart)) {
if (parentContainer instanceof EmbeddableValuedModelPart) {
if (embeddablePathSb == null) {
embeddablePathSb = new StringBuilder();
}
embeddablePathSb.insert(0, parentContainer.getPartName() + ".");
parentTableGroup = fromClauseAccess.findTableGroup(parentTableGroup.getNavigablePath().getParent());
parentContainer = parentTableGroup.getModelPart();
} else {
break;
}
}
final SqlAstJoinType joinType;
if (requestedJoinType == null) {
joinType = SqlAstJoinType.INNER;
} else {
joinType = requestedJoinType;
}
// we check if this attribute is the map key property to reuse the existing index table group
if (CollectionPart.Nature.ELEMENT.getName().equals(parentTableGroup.getNavigablePath().getUnaliasedLocalName()) && !addsPredicate && (joinType == SqlAstJoinType.INNER || joinType == SqlAstJoinType.LEFT)) {
final PluralTableGroup pluralTableGroup = (PluralTableGroup) fromClauseAccess.findTableGroup(parentTableGroup.getNavigablePath().getParent());
final String indexPropertyName = pluralTableGroup.getModelPart().getIndexMetadata().getIndexPropertyName();
final String pathName;
if (embeddablePathSb != null) {
pathName = embeddablePathSb.append(getAttributeName()).toString();
} else {
pathName = getAttributeName();
}
if (pathName.equals(indexPropertyName)) {
final TableGroup indexTableGroup = pluralTableGroup.getIndexTableGroup();
// If this is the map key property, we can reuse the index table group
initializeIfNeeded(lhs, requestedJoinType, indexTableGroup);
return new TableGroupJoin(navigablePath, joinType, new MappedByTableGroup(navigablePath, this, indexTableGroup, fetched, pluralTableGroup, (np, tableExpression) -> {
if (!canUseParentTableGroup) {
return false;
}
NavigablePath path = np.getParent();
// Fast path
if (path != null && navigablePath.equals(path)) {
return targetKeyPropertyNames.contains(np.getUnaliasedLocalName()) && identifyingColumnsTableExpression.equals(tableExpression);
}
final StringBuilder sb = new StringBuilder(np.getFullPath().length());
sb.append(np.getUnaliasedLocalName());
while (path != null && !navigablePath.equals(path)) {
sb.insert(0, '.');
sb.insert(0, path.getUnaliasedLocalName());
path = path.getParent();
}
return path != null && navigablePath.equals(path) && targetKeyPropertyNames.contains(sb.toString()) && identifyingColumnsTableExpression.equals(tableExpression);
}), null);
}
}
final LazyTableGroup lazyTableGroup = createRootTableGroupJoin(navigablePath, lhs, explicitSourceAlias, requestedJoinType, fetched, null, aliasBaseGenerator, sqlExpressionResolver, fromClauseAccess, creationContext);
final TableGroupJoin join = new TableGroupJoin(navigablePath, joinType, lazyTableGroup, null);
final TableReference lhsTableReference = lhs.resolveTableReference(navigablePath, identifyingColumnsTableExpression);
lazyTableGroup.setTableGroupInitializerCallback(tableGroup -> join.applyPredicate(foreignKeyDescriptor.generateJoinPredicate(sideNature == ForeignKeyDescriptor.Nature.TARGET ? lhsTableReference : tableGroup.getPrimaryTableReference(), sideNature == ForeignKeyDescriptor.Nature.TARGET ? tableGroup.getPrimaryTableReference() : lhsTableReference, sqlExpressionResolver, creationContext)));
return join;
}
use of org.hibernate.metamodel.mapping.ModelPartContainer in project hibernate-orm by hibernate.
the class ColumnReference method getTableReference.
TableReference getTableReference(TableGroup tableGroup) {
ModelPartContainer modelPart = tableGroup.getModelPart();
if (modelPart instanceof PluralAttributeMapping) {
final PluralAttributeMapping pluralAttribute = (PluralAttributeMapping) modelPart;
if (!pluralAttribute.getCollectionDescriptor().hasManyToManyOrdering()) {
return tableGroup.getPrimaryTableReference();
}
final MappingType elementMappingType = pluralAttribute.getElementDescriptor().getPartMappingType();
if (elementMappingType instanceof AbstractEntityPersister) {
final AbstractEntityPersister abstractEntityPersister = (AbstractEntityPersister) elementMappingType;
final int tableNumber = abstractEntityPersister.determineTableNumberForColumn(columnExpression);
final String tableName = abstractEntityPersister.getTableName(tableNumber);
return tableGroup.getTableReference(tableGroup.getNavigablePath(), tableName);
} else {
return tableGroup.getPrimaryTableReference();
}
}
return null;
}
use of org.hibernate.metamodel.mapping.ModelPartContainer 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.ModelPartContainer in project hibernate-orm by hibernate.
the class SqmMappingModelHelper method resolveSqmPath.
private static ModelPart resolveSqmPath(SqmPath<?> sqmPath, MappingMetamodel domainModel, Function<NavigablePath, TableGroup> tableGroupLocator) {
if (sqmPath instanceof SqmTreatedPath) {
final SqmTreatedPath treatedPath = (SqmTreatedPath) sqmPath;
final EntityDomainType treatTargetType = treatedPath.getTreatTarget();
return domainModel.findEntityDescriptor(treatTargetType.getHibernateEntityName());
}
// see if the LHS is treated
if (sqmPath.getLhs() instanceof SqmTreatedPath) {
final SqmTreatedPath treatedPath = (SqmTreatedPath) sqmPath.getLhs();
final EntityDomainType treatTargetType = treatedPath.getTreatTarget();
final EntityPersister container = domainModel.findEntityDescriptor(treatTargetType.getHibernateEntityName());
return container.findSubPart(sqmPath.getNavigablePath().getLocalName(), container);
}
// Plural path parts are not joined and thus also have no table group
if (sqmPath instanceof AbstractSqmSpecificPluralPartPath<?>) {
final TableGroup lhsTableGroup = tableGroupLocator.apply(sqmPath.getLhs().getLhs().getNavigablePath());
final ModelPartContainer pluralPart = (ModelPartContainer) lhsTableGroup.getModelPart().findSubPart(sqmPath.getLhs().getReferencedPathSource().getPathName(), null);
final CollectionPart collectionPart = (CollectionPart) pluralPart.findSubPart(sqmPath.getReferencedPathSource().getPathName(), null);
// as that is the mapping type of the expression
if (collectionPart instanceof EntityCollectionPart) {
return ((EntityCollectionPart) collectionPart).getEntityMappingType();
}
return collectionPart;
}
if (sqmPath.getLhs() == null) {
final EntityDomainType<?> entityDomainType = (EntityDomainType<?>) sqmPath.getReferencedPathSource();
return domainModel.findEntityDescriptor(entityDomainType.getHibernateEntityName());
}
final TableGroup lhsTableGroup = tableGroupLocator.apply(sqmPath.getLhs().getNavigablePath());
final ModelPartContainer modelPart;
if (lhsTableGroup == null) {
modelPart = (ModelPartContainer) resolveSqmPath(sqmPath.getLhs(), domainModel, tableGroupLocator);
} else {
modelPart = lhsTableGroup.getModelPart();
}
return modelPart.findSubPart(sqmPath.getReferencedPathSource().getPathName(), null);
}
use of org.hibernate.metamodel.mapping.ModelPartContainer in project hibernate-orm by hibernate.
the class AbstractSqmFrom method resolvePathPart.
@Override
public SqmPath<?> resolvePathPart(String name, boolean isTerminal, SqmCreationState creationState) {
// Try to resolve an existing attribute join without ON clause
SqmPath<?> resolvedPath = null;
ModelPartContainer modelPartContainer = null;
for (SqmJoin<?, ?> sqmJoin : getSqmJoins()) {
// We can only match singular joins here, as plural path parts are interpreted like sub-queries
if (sqmJoin instanceof SqmSingularJoin<?, ?> && name.equals(sqmJoin.getReferencedPathSource().getPathName())) {
final SqmAttributeJoin<?, ?> attributeJoin = (SqmAttributeJoin<?, ?>) sqmJoin;
if (attributeJoin.getOn() == null) {
// todo (6.0): to match the expectation of the JPA spec I think we also have to check
// that the join type is INNER or the default join type for the attribute,
// but as far as I understand, in 5.x we expect to ignore this behavior
// if ( attributeJoin.getSqmJoinType() != SqmJoinType.INNER ) {
// if ( attributeJoin.getAttribute().isCollection() ) {
// continue;
// }
// if ( modelPartContainer == null ) {
// modelPartContainer = findModelPartContainer( attributeJoin, creationState );
// }
// final TableGroupJoinProducer joinProducer = (TableGroupJoinProducer) modelPartContainer.findSubPart(
// name,
// null
// );
// if ( attributeJoin.getSqmJoinType().getCorrespondingSqlJoinType() != joinProducer.getDefaultSqlAstJoinType( null ) ) {
// continue;
// }
// }
resolvedPath = sqmJoin;
if (attributeJoin.isFetched()) {
break;
}
}
}
}
if (resolvedPath != null) {
return resolvedPath;
}
final SqmPath<?> sqmPath = get(name);
creationState.getProcessingStateStack().getCurrent().getPathRegistry().register(sqmPath);
return sqmPath;
}
Aggregations