HHH-16555 Consider implicit treats when creating SqmJoinable's navigable path

This commit is contained in:
Marco Belladelli 2023-05-09 13:02:48 +02:00
parent 3bc4cac14f
commit 23a03fcb58
3 changed files with 54 additions and 3 deletions

View File

@ -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 <D> The (D)eclaring type
* @param <C> The {@link Collection} type
@ -156,6 +160,28 @@ public abstract class AbstractPluralAttribute<D, C, E>
);
}
@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();

View File

@ -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<D,J>
);
}
@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<D,J>
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();

View File

@ -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;
}