diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractPluralAttribute.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractPluralAttribute.java index 91baccdd19..38d45a5df3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractPluralAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractPluralAttribute.java @@ -12,6 +12,8 @@ import java.util.Collection; import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.internal.MetadataContext; import org.hibernate.metamodel.mapping.CollectionPart; +import org.hibernate.metamodel.model.domain.DomainType; +import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.metamodel.model.domain.PluralPersistentAttribute; import org.hibernate.metamodel.model.domain.SimpleDomainType; import org.hibernate.spi.NavigablePath; @@ -21,6 +23,8 @@ import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath; import org.hibernate.type.descriptor.java.JavaType; +import static org.hibernate.query.sqm.spi.SqmCreationHelper.buildSubNavigablePath; + /** * @param The (D)eclaring type * @param The {@link Collection} type @@ -156,6 +160,28 @@ public abstract class AbstractPluralAttribute ); } + @Override + public NavigablePath createNavigablePath(SqmPath parent, String alias) { + if ( parent == null ) { + throw new IllegalArgumentException( + "`lhs` cannot be null for a sub-navigable reference - " + getName() + ); + } + final SqmPathSource parentPathSource = parent.getReferencedPathSource(); + NavigablePath navigablePath = parent.getNavigablePath(); + if ( parentPathSource instanceof PluralPersistentAttribute ) { + navigablePath = navigablePath.append( CollectionPart.Nature.ELEMENT.getName() ); + } + final DomainType parentType = parentPathSource.getSqmPathType(); + if ( parentType != getDeclaringType() && parentType instanceof EntityDomainType && + ( (EntityDomainType) parentType ).findPluralAttribute( getName() ) == null ) { + // If the parent path is an entity type which does not contain the joined attribute + // add an implicit treat to the parent's navigable path + navigablePath = navigablePath.treatAs( getDeclaringType().getTypeName() ); + } + return buildSubNavigablePath( navigablePath, getName(), alias ); + } + @Override public boolean isGeneric() { return elementPathSource.isGeneric(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/SingularAttributeImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/SingularAttributeImpl.java index b085a9ab93..6574e75b68 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/SingularAttributeImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/SingularAttributeImpl.java @@ -16,6 +16,7 @@ import org.hibernate.metamodel.internal.MetadataContext; import org.hibernate.metamodel.mapping.CollectionPart; import org.hibernate.metamodel.model.domain.AnyMappingDomainType; import org.hibernate.metamodel.model.domain.DomainType; +import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.metamodel.model.domain.IdentifiableDomainType; import org.hibernate.metamodel.model.domain.ManagedDomainType; import org.hibernate.metamodel.model.domain.PluralPersistentAttribute; @@ -35,6 +36,8 @@ import org.hibernate.spi.EntityIdentifierNavigablePath; import org.hibernate.spi.NavigablePath; import org.hibernate.type.descriptor.java.JavaType; +import static org.hibernate.query.sqm.spi.SqmCreationHelper.buildSubNavigablePath; + /** * @author Emmanuel Bernard * @author Steve Ebersole @@ -159,6 +162,28 @@ public class SingularAttributeImpl ); } + @Override + public NavigablePath createNavigablePath(SqmPath parent, String alias) { + if ( parent == null ) { + throw new IllegalArgumentException( + "`lhs` cannot be null for a sub-navigable reference - " + getName() + ); + } + final SqmPathSource parentPathSource = parent.getReferencedPathSource(); + NavigablePath navigablePath = parent.getNavigablePath(); + if ( parentPathSource instanceof PluralPersistentAttribute ) { + navigablePath = navigablePath.append( CollectionPart.Nature.ELEMENT.getName() ); + } + final DomainType parentType = parentPathSource.getSqmPathType(); + if ( parentType != getDeclaringType() && parentType instanceof EntityDomainType && + ( (EntityDomainType) parentType ).findSingularAttribute( getName() ) == null ) { + // If the parent path is an entity type which does not contain the joined attribute + // add an implicit treat to the parent's navigable path + navigablePath = navigablePath.treatAs( getDeclaringType().getTypeName() ); + } + return buildSubNavigablePath( navigablePath, getName(), alias ); + } + /** * Subclass used to simplify instantiation of singular attributes representing an entity's * identifier. @@ -191,7 +216,7 @@ public class SingularAttributeImpl public NavigablePath createNavigablePath(SqmPath parent, String alias) { if ( parent == null ) { throw new IllegalArgumentException( - "`lhs` cannot be null for a sub-navigable reference - " + parent + "`lhs` cannot be null for a sub-navigable reference - " + getName() ); } NavigablePath navigablePath = parent.getNavigablePath(); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityResultImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityResultImpl.java index 79d9c6de3e..609792eb61 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityResultImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityResultImpl.java @@ -43,11 +43,11 @@ public class EntityResultImpl extends AbstractEntityResultGraphNode implements E @Override public NavigablePath resolveNavigablePath(Fetchable fetchable) { - if ( fetchable instanceof TableGroupProducer && getNavigablePath().isAliased() ) { + if ( fetchable instanceof TableGroupProducer ) { for ( TableGroupJoin tableGroupJoin : tableGroup.getTableGroupJoins() ) { final NavigablePath navigablePath = tableGroupJoin.getNavigablePath(); if ( tableGroupJoin.getJoinedGroup().isFetched() - && fetchable.getNavigableRole().getLocalName().equals( navigablePath.getLocalName() ) + && fetchable.getFetchableName().equals( navigablePath.getLocalName() ) && tableGroupJoin.getJoinedGroup().getModelPart() == fetchable ) { return navigablePath; }