diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AbstractIdentifiableType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AbstractIdentifiableType.java index 6b2ab31605..1a9ab3275c 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AbstractIdentifiableType.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AbstractIdentifiableType.java @@ -414,6 +414,7 @@ public abstract class AbstractIdentifiableType if ( type instanceof BasicDomainType ) { return new BasicSqmPathSource<>( EntityIdentifierMapping.ROLE_LOCAL_NAME, + (SqmPathSource) id, (BasicDomainType) type, Bindable.BindableType.SINGULAR_ATTRIBUTE ); @@ -423,6 +424,7 @@ public abstract class AbstractIdentifiableType final EmbeddableDomainType compositeType = (EmbeddableDomainType) type; return new EmbeddedSqmPathSource<>( EntityIdentifierMapping.ROLE_LOCAL_NAME, + (SqmPathSource) id, compositeType, Bindable.BindableType.SINGULAR_ATTRIBUTE, id.isGeneric() @@ -434,6 +436,7 @@ public abstract class AbstractIdentifiableType if ( idClassType == null ) { return new NonAggregatedCompositeSqmPathSource<>( EntityIdentifierMapping.ROLE_LOCAL_NAME, + null, Bindable.BindableType.SINGULAR_ATTRIBUTE, this ); @@ -441,6 +444,7 @@ public abstract class AbstractIdentifiableType else { return new EmbeddedSqmPathSource<>( EntityIdentifierMapping.ROLE_LOCAL_NAME, + null, idClassType, Bindable.BindableType.SINGULAR_ATTRIBUTE, false diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/SingularPersistentAttribute.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/SingularPersistentAttribute.java index 4bdb99a31d..14276546fd 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/SingularPersistentAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/SingularPersistentAttribute.java @@ -27,6 +27,8 @@ public interface SingularPersistentAttribute @Override DomainType getSqmPathType(); + SqmPathSource getPathSource(); + /** * For a singular attribute, the value type is defined as the * attribute type diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractSqmPathSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractSqmPathSource.java index 4007b1cbd0..d15018154d 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractSqmPathSource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractSqmPathSource.java @@ -15,14 +15,17 @@ import org.hibernate.type.descriptor.java.JavaType; */ public abstract class AbstractSqmPathSource implements SqmPathSource { private final String localPathName; + protected final SqmPathSource pathModel; private final DomainType domainType; private final BindableType jpaBindableType; public AbstractSqmPathSource( String localPathName, + SqmPathSource pathModel, DomainType domainType, BindableType jpaBindableType) { this.localPathName = localPathName; + this.pathModel = pathModel == null ? this : pathModel; this.domainType = domainType; this.jpaBindableType = jpaBindableType; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyDiscriminatorSqmPath.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyDiscriminatorSqmPath.java index e37a08c0c3..c5fd2ba30c 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyDiscriminatorSqmPath.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyDiscriminatorSqmPath.java @@ -12,6 +12,7 @@ import org.hibernate.query.PathException; import org.hibernate.query.hql.spi.SqmCreationState; import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; +import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.SqmCopyContext; import org.hibernate.query.sqm.tree.domain.AbstractSqmPath; import org.hibernate.query.sqm.tree.domain.SqmPath; @@ -22,7 +23,7 @@ public class AnyDiscriminatorSqmPath extends AbstractSqmPath { protected AnyDiscriminatorSqmPath( NavigablePath navigablePath, - AnyDiscriminatorSqmPathSource referencedPathSource, + SqmPathSource referencedPathSource, SqmPath lhs, NodeBuilder nodeBuilder) { super( navigablePath, referencedPathSource, lhs, nodeBuilder ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyDiscriminatorSqmPathSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyDiscriminatorSqmPathSource.java index 8c97a09c5a..0e9ca32446 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyDiscriminatorSqmPathSource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyDiscriminatorSqmPathSource.java @@ -23,9 +23,10 @@ public class AnyDiscriminatorSqmPathSource extends AbstractSqmPathSource public AnyDiscriminatorSqmPathSource( String localPathName, + SqmPathSource pathModel, SimpleDomainType domainType, BindableType jpaBindableType) { - super( localPathName, domainType, jpaBindableType ); + super( localPathName, pathModel, domainType, jpaBindableType ); } @Override @@ -37,7 +38,7 @@ public class AnyDiscriminatorSqmPathSource extends AbstractSqmPathSource else { navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ); } - return new AnyDiscriminatorSqmPath( navigablePath, this, lhs, lhs.nodeBuilder() ); + return new AnyDiscriminatorSqmPath( navigablePath, pathModel, lhs, lhs.nodeBuilder() ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyMappingSqmPathSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyMappingSqmPathSource.java index d0abeac0b1..fb2764035d 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyMappingSqmPathSource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyMappingSqmPathSource.java @@ -13,8 +13,6 @@ import org.hibernate.spi.NavigablePath; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.domain.SqmAnyValuedSimplePath; import org.hibernate.query.sqm.tree.domain.SqmPath; -import org.hibernate.type.BasicType; -import org.hibernate.type.ConvertedBasicType; import static jakarta.persistence.metamodel.Bindable.BindableType.SINGULAR_ATTRIBUTE; @@ -27,12 +25,19 @@ public class AnyMappingSqmPathSource extends AbstractSqmPathSource { public AnyMappingSqmPathSource( String localPathName, + SqmPathSource pathModel, AnyMappingDomainType domainType, BindableType jpaBindableType) { - super( localPathName, domainType, jpaBindableType ); - keyPathSource = new BasicSqmPathSource<>( "id", (BasicDomainType) domainType.getKeyType(), SINGULAR_ATTRIBUTE ); + super( localPathName, pathModel, domainType, jpaBindableType ); + keyPathSource = new BasicSqmPathSource<>( + "id", + null, + (BasicDomainType) domainType.getKeyType(), + SINGULAR_ATTRIBUTE + ); discriminatorPathSource = new AnyDiscriminatorSqmPathSource<>( localPathName, + null, domainType.getDiscriminatorType(), jpaBindableType ); @@ -64,6 +69,6 @@ public class AnyMappingSqmPathSource extends AbstractSqmPathSource { else { navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() ); } - return new SqmAnyValuedSimplePath<>( navigablePath, this, lhs, lhs.nodeBuilder() ); + return new SqmAnyValuedSimplePath<>( navigablePath, pathModel, lhs, lhs.nodeBuilder() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/BasicSqmPathSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/BasicSqmPathSource.java index 986828b0f8..a945abd1e2 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/BasicSqmPathSource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/BasicSqmPathSource.java @@ -22,9 +22,10 @@ public class BasicSqmPathSource public BasicSqmPathSource( String localPathName, + SqmPathSource pathModel, BasicDomainType domainType, BindableType jpaBindableType) { - super( localPathName, domainType, jpaBindableType ); + super( localPathName, pathModel, domainType, jpaBindableType ); } @Override @@ -49,7 +50,7 @@ public class BasicSqmPathSource } return new SqmBasicValuedSimplePath<>( navigablePath, - this, + pathModel, lhs, lhs.nodeBuilder() ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/DiscriminatorSqmPathSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/DiscriminatorSqmPathSource.java index 0760f0d25e..ed14ee79ff 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/DiscriminatorSqmPathSource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/DiscriminatorSqmPathSource.java @@ -29,7 +29,7 @@ public class DiscriminatorSqmPathSource extends AbstractSqmPathSource DomainType discriminatorValueType, EntityDomainType entityDomainType, EntityMappingType entityMapping) { - super( EntityDiscriminatorMapping.ROLE_NAME, discriminatorValueType, BindableType.SINGULAR_ATTRIBUTE ); + super( EntityDiscriminatorMapping.ROLE_NAME, null, discriminatorValueType, BindableType.SINGULAR_ATTRIBUTE ); this.entityDomainType = entityDomainType; this.entityMapping = entityMapping; } @@ -43,7 +43,7 @@ public class DiscriminatorSqmPathSource extends AbstractSqmPathSource else { navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() ); } - return new DiscriminatorSqmPath( navigablePath, this, lhs, entityDomainType, entityMapping, lhs.nodeBuilder() ); + return new DiscriminatorSqmPath( navigablePath, pathModel, lhs, entityDomainType, entityMapping, lhs.nodeBuilder() ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EmbeddedSqmPathSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EmbeddedSqmPathSource.java index f343a433bc..6861ea91f9 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EmbeddedSqmPathSource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EmbeddedSqmPathSource.java @@ -22,10 +22,11 @@ public class EmbeddedSqmPathSource public EmbeddedSqmPathSource( String localPathName, + SqmPathSource pathModel, EmbeddableDomainType domainType, BindableType jpaBindableType, boolean isGeneric) { - super( localPathName, domainType, jpaBindableType ); + super( localPathName, pathModel, domainType, jpaBindableType ); this.isGeneric = isGeneric; } @@ -56,7 +57,7 @@ public class EmbeddedSqmPathSource } return new SqmEmbeddedValuedSimplePath<>( navigablePath, - this, + pathModel, lhs, lhs.nodeBuilder() ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EntitySqmPathSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EntitySqmPathSource.java index a854a08636..2f4408c9e5 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EntitySqmPathSource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EntitySqmPathSource.java @@ -23,9 +23,10 @@ import org.hibernate.query.sqm.tree.from.SqmFrom; public class EntitySqmPathSource extends AbstractSqmPathSource implements SqmJoinable { public EntitySqmPathSource( String localPathName, + SqmPathSource pathModel, EntityDomainType domainType, BindableType jpaBindableType) { - super( localPathName, domainType, jpaBindableType ); + super( localPathName, pathModel, domainType, jpaBindableType ); } @Override @@ -51,7 +52,7 @@ public class EntitySqmPathSource extends AbstractSqmPathSource implements } return new SqmEntityValuedSimplePath<>( navigablePath, - this, + pathModel, lhs, lhs.nodeBuilder() ); @@ -66,7 +67,7 @@ public class EntitySqmPathSource extends AbstractSqmPathSource implements SqmCreationState creationState) { return new SqmPluralPartJoin<>( lhs, - this, + pathModel, alias, joinType, creationState.getCreationContext().getNodeBuilder() diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/MappedSuperclassSqmPathSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/MappedSuperclassSqmPathSource.java index 5f10c093ae..616987e5fc 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/MappedSuperclassSqmPathSource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/MappedSuperclassSqmPathSource.java @@ -23,9 +23,10 @@ import org.hibernate.query.sqm.tree.from.SqmFrom; public class MappedSuperclassSqmPathSource extends AbstractSqmPathSource implements SqmJoinable { public MappedSuperclassSqmPathSource( String localPathName, + SqmPathSource pathModel, MappedSuperclassDomainType domainType, BindableType jpaBindableType) { - super( localPathName, domainType, jpaBindableType ); + super( localPathName, pathModel, domainType, jpaBindableType ); } @Override @@ -51,7 +52,7 @@ public class MappedSuperclassSqmPathSource extends AbstractSqmPathSource i } return new SqmEntityValuedSimplePath<>( navigablePath, - this, + pathModel, lhs, lhs.nodeBuilder() ); @@ -66,7 +67,7 @@ public class MappedSuperclassSqmPathSource extends AbstractSqmPathSource i SqmCreationState creationState) { return new SqmPluralPartJoin<>( lhs, - this, + pathModel, alias, joinType, creationState.getCreationContext().getNodeBuilder() diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/NonAggregatedCompositeSqmPathSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/NonAggregatedCompositeSqmPathSource.java index 7e9c90562d..c6bbaa41f7 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/NonAggregatedCompositeSqmPathSource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/NonAggregatedCompositeSqmPathSource.java @@ -20,9 +20,10 @@ import org.hibernate.query.sqm.tree.domain.SqmPath; public class NonAggregatedCompositeSqmPathSource extends AbstractSqmPathSource implements CompositeSqmPathSource { public NonAggregatedCompositeSqmPathSource( String localName, + SqmPathSource pathModel, BindableType bindableType, ManagedDomainType container) { - super( localName, container, bindableType ); + super( localName, pathModel, container, bindableType ); } @Override @@ -46,7 +47,7 @@ public class NonAggregatedCompositeSqmPathSource extends AbstractSqmPathSourc } return new NonAggregatedCompositeSimplePath<>( navigablePath, - this, + pathModel, lhs, lhs.nodeBuilder() ); 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 4a02e5d358..87845cac16 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 @@ -77,6 +77,7 @@ public class SingularAttributeImpl this.sqmPathSource = SqmMappingModelHelper.resolveSqmPathSource( name, + this, attributeType, BindableType.SINGULAR_ATTRIBUTE, isGeneric @@ -123,6 +124,11 @@ public class SingularAttributeImpl return sqmPathSource.findSubPathSource( name ); } + @Override + public SqmPathSource getPathSource() { + return this.sqmPathSource; + } + @Override public boolean isGeneric() { return sqmPathSource.isGeneric(); diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/JpaPath.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/JpaPath.java index 9a15b1eb4f..bba385ed20 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/JpaPath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/JpaPath.java @@ -15,6 +15,7 @@ import jakarta.persistence.metamodel.PluralAttribute; import jakarta.persistence.metamodel.SingularAttribute; import org.hibernate.metamodel.model.domain.EntityDomainType; +import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.spi.NavigablePath; /** @@ -43,6 +44,11 @@ public interface JpaPath extends JpaExpression, Path { */ JpaPath treatAs(EntityDomainType treatJavaType); + /** + * Get this pat's actual resolved model, e.g. the + * concrete embeddable type for generic embeddables + */ + SqmPathSource getResolvedModel(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Covariant overrides diff --git a/hibernate-core/src/main/java/org/hibernate/query/derived/AnonymousTupleSqmAssociationPathSource.java b/hibernate-core/src/main/java/org/hibernate/query/derived/AnonymousTupleSqmAssociationPathSource.java index 22faafbc17..ea9c56b942 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/derived/AnonymousTupleSqmAssociationPathSource.java +++ b/hibernate-core/src/main/java/org/hibernate/query/derived/AnonymousTupleSqmAssociationPathSource.java @@ -14,6 +14,7 @@ import org.hibernate.metamodel.model.domain.ManagedDomainType; import org.hibernate.metamodel.model.domain.SimpleDomainType; import org.hibernate.metamodel.model.domain.SingularPersistentAttribute; import org.hibernate.query.hql.spi.SqmCreationState; +import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.SqmJoinType; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmSingularJoin; @@ -65,6 +66,11 @@ public class AnonymousTupleSqmAssociationPathSource extends AnonymousTuple return null; } + @Override + public SqmPathSource getPathSource() { + return this; + } + @Override public boolean isId() { return false; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmMappingModelHelper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmMappingModelHelper.java index 8654ed9b3a..518ab4fffe 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmMappingModelHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmMappingModelHelper.java @@ -78,11 +78,12 @@ public class SqmMappingModelHelper { String name, DomainType valueDomainType, Bindable.BindableType jpaBindableType) { - return resolveSqmPathSource( name, valueDomainType, jpaBindableType, false ); + return resolveSqmPathSource( name, null, valueDomainType, jpaBindableType, false ); } public static SqmPathSource resolveSqmPathSource( String name, + SqmPathSource pathModel, DomainType valueDomainType, Bindable.BindableType jpaBindableType, boolean isGeneric) { @@ -90,6 +91,7 @@ public class SqmMappingModelHelper { if ( valueDomainType instanceof BasicDomainType ) { return new BasicSqmPathSource<>( name, + pathModel, (BasicDomainType) valueDomainType, jpaBindableType ); @@ -98,6 +100,7 @@ public class SqmMappingModelHelper { if ( valueDomainType instanceof AnyMappingDomainType ) { return new AnyMappingSqmPathSource<>( name, + pathModel, (AnyMappingDomainType) valueDomainType, jpaBindableType ); @@ -106,6 +109,7 @@ public class SqmMappingModelHelper { if ( valueDomainType instanceof EmbeddableDomainType ) { return new EmbeddedSqmPathSource<>( name, + pathModel, (EmbeddableDomainType) valueDomainType, jpaBindableType, isGeneric @@ -115,6 +119,7 @@ public class SqmMappingModelHelper { if ( valueDomainType instanceof EntityDomainType ) { return new EntitySqmPathSource<>( name, + pathModel, (EntityDomainType) valueDomainType, jpaBindableType ); @@ -123,6 +128,7 @@ public class SqmMappingModelHelper { if ( valueDomainType instanceof MappedSuperclassDomainType ) { return new MappedSuperclassSqmPathSource<>( name, + pathModel, (MappedSuperclassDomainType) valueDomainType, jpaBindableType ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java index 72bda41edc..2cb22677ed 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java @@ -138,6 +138,11 @@ public abstract class AbstractSqmPath extends AbstractSqmExpression implem return getReferencedPathSource(); } + @Override + public SqmPathSource getResolvedModel() { + return getModel(); + } + @Override @SuppressWarnings("unchecked") public SqmExpression> type() { diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmSimplePath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmSimplePath.java index 95cc6363cf..f0ad3c937f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmSimplePath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmSimplePath.java @@ -6,6 +6,7 @@ */ package org.hibernate.query.sqm.tree.domain; +import org.hibernate.metamodel.model.domain.SingularPersistentAttribute; import org.hibernate.spi.NavigablePath; import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SqmPathSource; @@ -42,4 +43,23 @@ public abstract class AbstractSqmSimplePath extends AbstractSqmPath implem } sb.append( getReferencedPathSource().getPathName() ); } + + @Override + public SqmPathSource getNodeType() { + return getReferencedPathSource(); + } + + @Override + public SqmPathSource getReferencedPathSource() { + final SqmPathSource pathSource = super.getNodeType(); + if ( pathSource instanceof SingularPersistentAttribute ) { + return ( (SingularPersistentAttribute) pathSource ).getPathSource(); + } + return pathSource; + } + + @Override + public SqmPathSource getModel() { + return super.getNodeType(); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmEmbeddedValuedSimplePath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmEmbeddedValuedSimplePath.java index d3e9726958..093bb09f28 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmEmbeddedValuedSimplePath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmEmbeddedValuedSimplePath.java @@ -82,6 +82,12 @@ public class SqmEmbeddedValuedSimplePath @Override public SqmPath get(String attributeName) { + final SqmPathSource subNavigable = getResolvedModel().getSubPathSource( attributeName ); + return resolvePath( attributeName, subNavigable ); + } + + @Override + public SqmPathSource getResolvedModel() { final DomainType lhsType; final SqmPathSource pathSource = getReferencedPathSource(); if ( pathSource.isGeneric() && ( lhsType = getLhs().getReferencedPathSource() @@ -91,11 +97,10 @@ public class SqmEmbeddedValuedSimplePath pathSource.getPathName() ); if ( concreteEmbeddable != null ) { - final SqmPathSource subNavigable = concreteEmbeddable.getSubPathSource( attributeName ); - return resolvePath( attributeName, subNavigable ); + return concreteEmbeddable; } } - return super.get( attributeName ); + return getModel(); } @Override @@ -128,6 +133,4 @@ public class SqmEmbeddedValuedSimplePath public Class getBindableJavaType() { return getJavaType(); } - - } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/generics/EmbeddedIdGenericsSuperclassTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/generics/EmbeddedIdGenericsSuperclassTest.java index 7968d29184..952f83f9e8 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/generics/EmbeddedIdGenericsSuperclassTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/generics/EmbeddedIdGenericsSuperclassTest.java @@ -9,6 +9,8 @@ package org.hibernate.orm.test.annotations.generics; import java.io.Serializable; import java.util.Random; +import org.hibernate.query.criteria.JpaPath; + import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.Jira; import org.hibernate.testing.orm.junit.SessionFactory; @@ -79,9 +81,10 @@ public class EmbeddedIdGenericsSuperclassTest { final CriteriaBuilder cb = session.getCriteriaBuilder(); final CriteriaQuery query = cb.createQuery( Customer.class ); final Root root = query.from( Customer.class ); - final Path id = root.get( "id" ); - assertThat( id ).isNotNull(); - assertThat( id.getJavaType() ).isEqualTo( CustomerId.class ); + final Path id = root.get( "id" ); + assertThat( id.getJavaType() ).isEqualTo( DomainEntityId.class ); + assertThat( id.getModel() ).isSameAs( root.getModel().getAttribute( "id" ) ); + assertThat( ( (JpaPath) id ).getResolvedModel().getBindableJavaType() ).isEqualTo( CustomerId.class ); query.select( root ).where( cb.equal( id.get( "someDomainField" ), 1 ) ); final Customer customer = session.createQuery( query ).getSingleResult(); assertThat( customer ).isNotNull(); @@ -108,9 +111,10 @@ public class EmbeddedIdGenericsSuperclassTest { final CriteriaBuilder cb = session.getCriteriaBuilder(); final CriteriaQuery query = cb.createQuery( Invoice.class ); final Root root = query.from( Invoice.class ); - final Path id = root.get( "id" ); - assertThat( id ).isNotNull(); - assertThat( id.getJavaType() ).isEqualTo( InvoiceId.class ); + final Path id = root.get( "id" ); + assertThat( id.getJavaType() ).isEqualTo( DomainEntityId.class ); + assertThat( id.getModel() ).isSameAs( root.getModel().getAttribute( "id" ) ); + assertThat( ( (JpaPath) id ).getResolvedModel().getBindableJavaType() ).isEqualTo( InvoiceId.class ); query.select( root ).where( cb.equal( id.get( "someOtherDomainField" ), 1 ) ); final Invoice invoice = session.createQuery( query ).getSingleResult(); assertThat( invoice ).isNotNull(); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/generics/MultipleEmbeddedGenericsTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/generics/MultipleEmbeddedGenericsTest.java index 7c25d20a51..5fd26b6901 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/generics/MultipleEmbeddedGenericsTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/generics/MultipleEmbeddedGenericsTest.java @@ -6,6 +6,8 @@ */ package org.hibernate.orm.test.annotations.generics; +import org.hibernate.query.criteria.JpaPath; + import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.Jira; import org.hibernate.testing.orm.junit.SessionFactory; @@ -35,7 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat; MultipleEmbeddedGenericsTest.Invoice.class }) @SessionFactory -@Jira("https://hibernate.atlassian.net/browse/HHH-TODO") // todo marco : create specific issue for this +@Jira("https://hibernate.atlassian.net/browse/HHH-16238") public class MultipleEmbeddedGenericsTest { @BeforeAll public void setUp(SessionFactoryScope scope) { @@ -75,9 +77,13 @@ public class MultipleEmbeddedGenericsTest { final Path firstEmbedded = root.get( "firstEmbedded" ); assertThat( firstEmbedded.getJavaType() ).isEqualTo( GenericEmbeddableOne.class ); assertThat( firstEmbedded.getModel() ).isSameAs( root.getModel().getAttribute( "firstEmbedded" ) ); + assertThat( ( (JpaPath) firstEmbedded ).getResolvedModel().getBindableJavaType() ) + .isEqualTo( CustomerEmbeddableOne.class ); final Path secondEmbedded = root.get( "secondEmbedded" ); assertThat( secondEmbedded.getJavaType() ).isEqualTo( GenericEmbeddableTwo.class ); assertThat( secondEmbedded.getModel() ).isSameAs( root.getModel().getAttribute( "secondEmbedded" ) ); + assertThat( ( (JpaPath) secondEmbedded ).getResolvedModel().getBindableJavaType() ) + .isEqualTo( CustomerEmbeddableTwo.class ); query.select( root ).where( cb.and( cb.equal( firstEmbedded.get( "genericPropertyA" ), "1" ), cb.equal( secondEmbedded.get( "customerPropertyB" ), 2 ) @@ -107,9 +113,13 @@ public class MultipleEmbeddedGenericsTest { final Path firstEmbedded = root.get( "firstEmbedded" ); assertThat( firstEmbedded.getJavaType() ).isEqualTo( GenericEmbeddableOne.class ); assertThat( firstEmbedded.getModel() ).isSameAs( root.getModel().getAttribute( "firstEmbedded" ) ); + assertThat( ( (JpaPath) firstEmbedded ).getResolvedModel().getBindableJavaType() ) + .isEqualTo( InvoiceEmbeddableOne.class ); final Path secondEmbedded = root.get( "secondEmbedded" ); assertThat( secondEmbedded.getJavaType() ).isEqualTo( GenericEmbeddableTwo.class ); assertThat( secondEmbedded.getModel() ).isSameAs( root.getModel().getAttribute( "secondEmbedded" ) ); + assertThat( ( (JpaPath) secondEmbedded ).getResolvedModel().getBindableJavaType() ) + .isEqualTo( InvoiceEmbeddableTwo.class ); query.select( root ).where( cb.and( cb.equal( firstEmbedded.get( "invoicePropertyA" ), 1 ), cb.equal( secondEmbedded.get( "genericPropertyB" ), "2" )