HHH-16238 Correct path model in createSqmPath for SingularAttributeImpl

This commit is contained in:
Marco Belladelli 2023-03-02 16:29:52 +01:00 committed by Christian Beikov
parent 16c9b1f5b7
commit e896656bb3
21 changed files with 122 additions and 35 deletions

View File

@ -414,6 +414,7 @@ public abstract class AbstractIdentifiableType<J>
if ( type instanceof BasicDomainType ) { if ( type instanceof BasicDomainType ) {
return new BasicSqmPathSource<>( return new BasicSqmPathSource<>(
EntityIdentifierMapping.ROLE_LOCAL_NAME, EntityIdentifierMapping.ROLE_LOCAL_NAME,
(SqmPathSource) id,
(BasicDomainType<?>) type, (BasicDomainType<?>) type,
Bindable.BindableType.SINGULAR_ATTRIBUTE Bindable.BindableType.SINGULAR_ATTRIBUTE
); );
@ -423,6 +424,7 @@ public abstract class AbstractIdentifiableType<J>
final EmbeddableDomainType<?> compositeType = (EmbeddableDomainType<?>) type; final EmbeddableDomainType<?> compositeType = (EmbeddableDomainType<?>) type;
return new EmbeddedSqmPathSource<>( return new EmbeddedSqmPathSource<>(
EntityIdentifierMapping.ROLE_LOCAL_NAME, EntityIdentifierMapping.ROLE_LOCAL_NAME,
(SqmPathSource) id,
compositeType, compositeType,
Bindable.BindableType.SINGULAR_ATTRIBUTE, Bindable.BindableType.SINGULAR_ATTRIBUTE,
id.isGeneric() id.isGeneric()
@ -434,6 +436,7 @@ public abstract class AbstractIdentifiableType<J>
if ( idClassType == null ) { if ( idClassType == null ) {
return new NonAggregatedCompositeSqmPathSource<>( return new NonAggregatedCompositeSqmPathSource<>(
EntityIdentifierMapping.ROLE_LOCAL_NAME, EntityIdentifierMapping.ROLE_LOCAL_NAME,
null,
Bindable.BindableType.SINGULAR_ATTRIBUTE, Bindable.BindableType.SINGULAR_ATTRIBUTE,
this this
); );
@ -441,6 +444,7 @@ public abstract class AbstractIdentifiableType<J>
else { else {
return new EmbeddedSqmPathSource<>( return new EmbeddedSqmPathSource<>(
EntityIdentifierMapping.ROLE_LOCAL_NAME, EntityIdentifierMapping.ROLE_LOCAL_NAME,
null,
idClassType, idClassType,
Bindable.BindableType.SINGULAR_ATTRIBUTE, Bindable.BindableType.SINGULAR_ATTRIBUTE,
false false

View File

@ -27,6 +27,8 @@ public interface SingularPersistentAttribute<D,J>
@Override @Override
DomainType<J> getSqmPathType(); DomainType<J> getSqmPathType();
SqmPathSource<J> getPathSource();
/** /**
* For a singular attribute, the value type is defined as the * For a singular attribute, the value type is defined as the
* attribute type * attribute type

View File

@ -15,14 +15,17 @@ import org.hibernate.type.descriptor.java.JavaType;
*/ */
public abstract class AbstractSqmPathSource<J> implements SqmPathSource<J> { public abstract class AbstractSqmPathSource<J> implements SqmPathSource<J> {
private final String localPathName; private final String localPathName;
protected final SqmPathSource<J> pathModel;
private final DomainType<J> domainType; private final DomainType<J> domainType;
private final BindableType jpaBindableType; private final BindableType jpaBindableType;
public AbstractSqmPathSource( public AbstractSqmPathSource(
String localPathName, String localPathName,
SqmPathSource<J> pathModel,
DomainType<J> domainType, DomainType<J> domainType,
BindableType jpaBindableType) { BindableType jpaBindableType) {
this.localPathName = localPathName; this.localPathName = localPathName;
this.pathModel = pathModel == null ? this : pathModel;
this.domainType = domainType; this.domainType = domainType;
this.jpaBindableType = jpaBindableType; this.jpaBindableType = jpaBindableType;
} }

View File

@ -12,6 +12,7 @@ import org.hibernate.query.PathException;
import org.hibernate.query.hql.spi.SqmCreationState; import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticQueryWalker; 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.SqmCopyContext;
import org.hibernate.query.sqm.tree.domain.AbstractSqmPath; import org.hibernate.query.sqm.tree.domain.AbstractSqmPath;
import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmPath;
@ -22,7 +23,7 @@ public class AnyDiscriminatorSqmPath<T> extends AbstractSqmPath<T> {
protected AnyDiscriminatorSqmPath( protected AnyDiscriminatorSqmPath(
NavigablePath navigablePath, NavigablePath navigablePath,
AnyDiscriminatorSqmPathSource referencedPathSource, SqmPathSource referencedPathSource,
SqmPath lhs, SqmPath lhs,
NodeBuilder nodeBuilder) { NodeBuilder nodeBuilder) {
super( navigablePath, referencedPathSource, lhs, nodeBuilder ); super( navigablePath, referencedPathSource, lhs, nodeBuilder );

View File

@ -23,9 +23,10 @@ public class AnyDiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
public AnyDiscriminatorSqmPathSource( public AnyDiscriminatorSqmPathSource(
String localPathName, String localPathName,
SqmPathSource<D> pathModel,
SimpleDomainType<D> domainType, SimpleDomainType<D> domainType,
BindableType jpaBindableType) { BindableType jpaBindableType) {
super( localPathName, domainType, jpaBindableType ); super( localPathName, pathModel, domainType, jpaBindableType );
} }
@Override @Override
@ -37,7 +38,7 @@ public class AnyDiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
else { else {
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ); navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() );
} }
return new AnyDiscriminatorSqmPath( navigablePath, this, lhs, lhs.nodeBuilder() ); return new AnyDiscriminatorSqmPath( navigablePath, pathModel, lhs, lhs.nodeBuilder() );
} }
@Override @Override

View File

@ -13,8 +13,6 @@ import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmAnyValuedSimplePath; import org.hibernate.query.sqm.tree.domain.SqmAnyValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath; 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; import static jakarta.persistence.metamodel.Bindable.BindableType.SINGULAR_ATTRIBUTE;
@ -27,12 +25,19 @@ public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
public AnyMappingSqmPathSource( public AnyMappingSqmPathSource(
String localPathName, String localPathName,
SqmPathSource<J> pathModel,
AnyMappingDomainType<J> domainType, AnyMappingDomainType<J> domainType,
BindableType jpaBindableType) { BindableType jpaBindableType) {
super( localPathName, domainType, jpaBindableType ); super( localPathName, pathModel, domainType, jpaBindableType );
keyPathSource = new BasicSqmPathSource<>( "id", (BasicDomainType<?>) domainType.getKeyType(), SINGULAR_ATTRIBUTE ); keyPathSource = new BasicSqmPathSource<>(
"id",
null,
(BasicDomainType<?>) domainType.getKeyType(),
SINGULAR_ATTRIBUTE
);
discriminatorPathSource = new AnyDiscriminatorSqmPathSource<>( discriminatorPathSource = new AnyDiscriminatorSqmPathSource<>(
localPathName, localPathName,
null,
domainType.getDiscriminatorType(), domainType.getDiscriminatorType(),
jpaBindableType jpaBindableType
); );
@ -64,6 +69,6 @@ public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
else { else {
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() ); navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() );
} }
return new SqmAnyValuedSimplePath<>( navigablePath, this, lhs, lhs.nodeBuilder() ); return new SqmAnyValuedSimplePath<>( navigablePath, pathModel, lhs, lhs.nodeBuilder() );
} }
} }

View File

@ -22,9 +22,10 @@ public class BasicSqmPathSource<J>
public BasicSqmPathSource( public BasicSqmPathSource(
String localPathName, String localPathName,
SqmPathSource<J> pathModel,
BasicDomainType<J> domainType, BasicDomainType<J> domainType,
BindableType jpaBindableType) { BindableType jpaBindableType) {
super( localPathName, domainType, jpaBindableType ); super( localPathName, pathModel, domainType, jpaBindableType );
} }
@Override @Override
@ -49,7 +50,7 @@ public class BasicSqmPathSource<J>
} }
return new SqmBasicValuedSimplePath<>( return new SqmBasicValuedSimplePath<>(
navigablePath, navigablePath,
this, pathModel,
lhs, lhs,
lhs.nodeBuilder() lhs.nodeBuilder()
); );

View File

@ -29,7 +29,7 @@ public class DiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
DomainType<D> discriminatorValueType, DomainType<D> discriminatorValueType,
EntityDomainType<?> entityDomainType, EntityDomainType<?> entityDomainType,
EntityMappingType entityMapping) { EntityMappingType entityMapping) {
super( EntityDiscriminatorMapping.ROLE_NAME, discriminatorValueType, BindableType.SINGULAR_ATTRIBUTE ); super( EntityDiscriminatorMapping.ROLE_NAME, null, discriminatorValueType, BindableType.SINGULAR_ATTRIBUTE );
this.entityDomainType = entityDomainType; this.entityDomainType = entityDomainType;
this.entityMapping = entityMapping; this.entityMapping = entityMapping;
} }
@ -43,7 +43,7 @@ public class DiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
else { else {
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() ); 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 @Override

View File

@ -22,10 +22,11 @@ public class EmbeddedSqmPathSource<J>
public EmbeddedSqmPathSource( public EmbeddedSqmPathSource(
String localPathName, String localPathName,
SqmPathSource<J> pathModel,
EmbeddableDomainType<J> domainType, EmbeddableDomainType<J> domainType,
BindableType jpaBindableType, BindableType jpaBindableType,
boolean isGeneric) { boolean isGeneric) {
super( localPathName, domainType, jpaBindableType ); super( localPathName, pathModel, domainType, jpaBindableType );
this.isGeneric = isGeneric; this.isGeneric = isGeneric;
} }
@ -56,7 +57,7 @@ public class EmbeddedSqmPathSource<J>
} }
return new SqmEmbeddedValuedSimplePath<>( return new SqmEmbeddedValuedSimplePath<>(
navigablePath, navigablePath,
this, pathModel,
lhs, lhs,
lhs.nodeBuilder() lhs.nodeBuilder()
); );

View File

@ -23,9 +23,10 @@ import org.hibernate.query.sqm.tree.from.SqmFrom;
public class EntitySqmPathSource<J> extends AbstractSqmPathSource<J> implements SqmJoinable<Object, J> { public class EntitySqmPathSource<J> extends AbstractSqmPathSource<J> implements SqmJoinable<Object, J> {
public EntitySqmPathSource( public EntitySqmPathSource(
String localPathName, String localPathName,
SqmPathSource<J> pathModel,
EntityDomainType<J> domainType, EntityDomainType<J> domainType,
BindableType jpaBindableType) { BindableType jpaBindableType) {
super( localPathName, domainType, jpaBindableType ); super( localPathName, pathModel, domainType, jpaBindableType );
} }
@Override @Override
@ -51,7 +52,7 @@ public class EntitySqmPathSource<J> extends AbstractSqmPathSource<J> implements
} }
return new SqmEntityValuedSimplePath<>( return new SqmEntityValuedSimplePath<>(
navigablePath, navigablePath,
this, pathModel,
lhs, lhs,
lhs.nodeBuilder() lhs.nodeBuilder()
); );
@ -66,7 +67,7 @@ public class EntitySqmPathSource<J> extends AbstractSqmPathSource<J> implements
SqmCreationState creationState) { SqmCreationState creationState) {
return new SqmPluralPartJoin<>( return new SqmPluralPartJoin<>(
lhs, lhs,
this, pathModel,
alias, alias,
joinType, joinType,
creationState.getCreationContext().getNodeBuilder() creationState.getCreationContext().getNodeBuilder()

View File

@ -23,9 +23,10 @@ import org.hibernate.query.sqm.tree.from.SqmFrom;
public class MappedSuperclassSqmPathSource<J> extends AbstractSqmPathSource<J> implements SqmJoinable<Object, J> { public class MappedSuperclassSqmPathSource<J> extends AbstractSqmPathSource<J> implements SqmJoinable<Object, J> {
public MappedSuperclassSqmPathSource( public MappedSuperclassSqmPathSource(
String localPathName, String localPathName,
SqmPathSource<J> pathModel,
MappedSuperclassDomainType<J> domainType, MappedSuperclassDomainType<J> domainType,
BindableType jpaBindableType) { BindableType jpaBindableType) {
super( localPathName, domainType, jpaBindableType ); super( localPathName, pathModel, domainType, jpaBindableType );
} }
@Override @Override
@ -51,7 +52,7 @@ public class MappedSuperclassSqmPathSource<J> extends AbstractSqmPathSource<J> i
} }
return new SqmEntityValuedSimplePath<>( return new SqmEntityValuedSimplePath<>(
navigablePath, navigablePath,
this, pathModel,
lhs, lhs,
lhs.nodeBuilder() lhs.nodeBuilder()
); );
@ -66,7 +67,7 @@ public class MappedSuperclassSqmPathSource<J> extends AbstractSqmPathSource<J> i
SqmCreationState creationState) { SqmCreationState creationState) {
return new SqmPluralPartJoin<>( return new SqmPluralPartJoin<>(
lhs, lhs,
this, pathModel,
alias, alias,
joinType, joinType,
creationState.getCreationContext().getNodeBuilder() creationState.getCreationContext().getNodeBuilder()

View File

@ -20,9 +20,10 @@ import org.hibernate.query.sqm.tree.domain.SqmPath;
public class NonAggregatedCompositeSqmPathSource<J> extends AbstractSqmPathSource<J> implements CompositeSqmPathSource<J> { public class NonAggregatedCompositeSqmPathSource<J> extends AbstractSqmPathSource<J> implements CompositeSqmPathSource<J> {
public NonAggregatedCompositeSqmPathSource( public NonAggregatedCompositeSqmPathSource(
String localName, String localName,
SqmPathSource<J> pathModel,
BindableType bindableType, BindableType bindableType,
ManagedDomainType<J> container) { ManagedDomainType<J> container) {
super( localName, container, bindableType ); super( localName, pathModel, container, bindableType );
} }
@Override @Override
@ -46,7 +47,7 @@ public class NonAggregatedCompositeSqmPathSource<J> extends AbstractSqmPathSourc
} }
return new NonAggregatedCompositeSimplePath<>( return new NonAggregatedCompositeSimplePath<>(
navigablePath, navigablePath,
this, pathModel,
lhs, lhs,
lhs.nodeBuilder() lhs.nodeBuilder()
); );

View File

@ -77,6 +77,7 @@ public class SingularAttributeImpl<D,J>
this.sqmPathSource = SqmMappingModelHelper.resolveSqmPathSource( this.sqmPathSource = SqmMappingModelHelper.resolveSqmPathSource(
name, name,
this,
attributeType, attributeType,
BindableType.SINGULAR_ATTRIBUTE, BindableType.SINGULAR_ATTRIBUTE,
isGeneric isGeneric
@ -123,6 +124,11 @@ public class SingularAttributeImpl<D,J>
return sqmPathSource.findSubPathSource( name ); return sqmPathSource.findSubPathSource( name );
} }
@Override
public SqmPathSource<J> getPathSource() {
return this.sqmPathSource;
}
@Override @Override
public boolean isGeneric() { public boolean isGeneric() {
return sqmPathSource.isGeneric(); return sqmPathSource.isGeneric();

View File

@ -15,6 +15,7 @@ import jakarta.persistence.metamodel.PluralAttribute;
import jakarta.persistence.metamodel.SingularAttribute; import jakarta.persistence.metamodel.SingularAttribute;
import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.spi.NavigablePath; import org.hibernate.spi.NavigablePath;
/** /**
@ -43,6 +44,11 @@ public interface JpaPath<T> extends JpaExpression<T>, Path<T> {
*/ */
<S extends T> JpaPath<S> treatAs(EntityDomainType<S> treatJavaType); <S extends T> JpaPath<S> treatAs(EntityDomainType<S> treatJavaType);
/**
* Get this pat's actual resolved model, e.g. the
* concrete embeddable type for generic embeddables
*/
SqmPathSource<?> getResolvedModel();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Covariant overrides // Covariant overrides

View File

@ -14,6 +14,7 @@ import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.SimpleDomainType; import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute; import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.query.hql.spi.SqmCreationState; 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.SqmJoinType;
import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmSingularJoin; import org.hibernate.query.sqm.tree.domain.SqmSingularJoin;
@ -65,6 +66,11 @@ public class AnonymousTupleSqmAssociationPathSource<O, J> extends AnonymousTuple
return null; return null;
} }
@Override
public SqmPathSource<J> getPathSource() {
return this;
}
@Override @Override
public boolean isId() { public boolean isId() {
return false; return false;

View File

@ -78,11 +78,12 @@ public class SqmMappingModelHelper {
String name, String name,
DomainType<J> valueDomainType, DomainType<J> valueDomainType,
Bindable.BindableType jpaBindableType) { Bindable.BindableType jpaBindableType) {
return resolveSqmPathSource( name, valueDomainType, jpaBindableType, false ); return resolveSqmPathSource( name, null, valueDomainType, jpaBindableType, false );
} }
public static <J> SqmPathSource<J> resolveSqmPathSource( public static <J> SqmPathSource<J> resolveSqmPathSource(
String name, String name,
SqmPathSource<J> pathModel,
DomainType<J> valueDomainType, DomainType<J> valueDomainType,
Bindable.BindableType jpaBindableType, Bindable.BindableType jpaBindableType,
boolean isGeneric) { boolean isGeneric) {
@ -90,6 +91,7 @@ public class SqmMappingModelHelper {
if ( valueDomainType instanceof BasicDomainType<?> ) { if ( valueDomainType instanceof BasicDomainType<?> ) {
return new BasicSqmPathSource<>( return new BasicSqmPathSource<>(
name, name,
pathModel,
(BasicDomainType<J>) valueDomainType, (BasicDomainType<J>) valueDomainType,
jpaBindableType jpaBindableType
); );
@ -98,6 +100,7 @@ public class SqmMappingModelHelper {
if ( valueDomainType instanceof AnyMappingDomainType<?> ) { if ( valueDomainType instanceof AnyMappingDomainType<?> ) {
return new AnyMappingSqmPathSource<>( return new AnyMappingSqmPathSource<>(
name, name,
pathModel,
(AnyMappingDomainType<J>) valueDomainType, (AnyMappingDomainType<J>) valueDomainType,
jpaBindableType jpaBindableType
); );
@ -106,6 +109,7 @@ public class SqmMappingModelHelper {
if ( valueDomainType instanceof EmbeddableDomainType<?> ) { if ( valueDomainType instanceof EmbeddableDomainType<?> ) {
return new EmbeddedSqmPathSource<>( return new EmbeddedSqmPathSource<>(
name, name,
pathModel,
(EmbeddableDomainType<J>) valueDomainType, (EmbeddableDomainType<J>) valueDomainType,
jpaBindableType, jpaBindableType,
isGeneric isGeneric
@ -115,6 +119,7 @@ public class SqmMappingModelHelper {
if ( valueDomainType instanceof EntityDomainType<?> ) { if ( valueDomainType instanceof EntityDomainType<?> ) {
return new EntitySqmPathSource<>( return new EntitySqmPathSource<>(
name, name,
pathModel,
(EntityDomainType<J>) valueDomainType, (EntityDomainType<J>) valueDomainType,
jpaBindableType jpaBindableType
); );
@ -123,6 +128,7 @@ public class SqmMappingModelHelper {
if ( valueDomainType instanceof MappedSuperclassDomainType<?> ) { if ( valueDomainType instanceof MappedSuperclassDomainType<?> ) {
return new MappedSuperclassSqmPathSource<>( return new MappedSuperclassSqmPathSource<>(
name, name,
pathModel,
(MappedSuperclassDomainType<J>) valueDomainType, (MappedSuperclassDomainType<J>) valueDomainType,
jpaBindableType jpaBindableType
); );

View File

@ -138,6 +138,11 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
return getReferencedPathSource(); return getReferencedPathSource();
} }
@Override
public SqmPathSource<?> getResolvedModel() {
return getModel();
}
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public SqmExpression<Class<? extends T>> type() { public SqmExpression<Class<? extends T>> type() {

View File

@ -6,6 +6,7 @@
*/ */
package org.hibernate.query.sqm.tree.domain; package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.spi.NavigablePath; import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.SqmPathSource;
@ -42,4 +43,23 @@ public abstract class AbstractSqmSimplePath<T> extends AbstractSqmPath<T> implem
} }
sb.append( getReferencedPathSource().getPathName() ); sb.append( getReferencedPathSource().getPathName() );
} }
@Override
public SqmPathSource<T> getNodeType() {
return getReferencedPathSource();
}
@Override
public SqmPathSource<T> getReferencedPathSource() {
final SqmPathSource<T> pathSource = super.getNodeType();
if ( pathSource instanceof SingularPersistentAttribute ) {
return ( (SingularPersistentAttribute<?, T>) pathSource ).getPathSource();
}
return pathSource;
}
@Override
public SqmPathSource<T> getModel() {
return super.getNodeType();
}
} }

View File

@ -82,6 +82,12 @@ public class SqmEmbeddedValuedSimplePath<T>
@Override @Override
public SqmPath<?> get(String attributeName) { public SqmPath<?> get(String attributeName) {
final SqmPathSource<?> subNavigable = getResolvedModel().getSubPathSource( attributeName );
return resolvePath( attributeName, subNavigable );
}
@Override
public SqmPathSource<?> getResolvedModel() {
final DomainType<?> lhsType; final DomainType<?> lhsType;
final SqmPathSource<T> pathSource = getReferencedPathSource(); final SqmPathSource<T> pathSource = getReferencedPathSource();
if ( pathSource.isGeneric() && ( lhsType = getLhs().getReferencedPathSource() if ( pathSource.isGeneric() && ( lhsType = getLhs().getReferencedPathSource()
@ -91,11 +97,10 @@ public class SqmEmbeddedValuedSimplePath<T>
pathSource.getPathName() pathSource.getPathName()
); );
if ( concreteEmbeddable != null ) { if ( concreteEmbeddable != null ) {
final SqmPathSource<?> subNavigable = concreteEmbeddable.getSubPathSource( attributeName ); return concreteEmbeddable;
return resolvePath( attributeName, subNavigable );
} }
} }
return super.get( attributeName ); return getModel();
} }
@Override @Override
@ -128,6 +133,4 @@ public class SqmEmbeddedValuedSimplePath<T>
public Class<T> getBindableJavaType() { public Class<T> getBindableJavaType() {
return getJavaType(); return getJavaType();
} }
} }

View File

@ -9,6 +9,8 @@ package org.hibernate.orm.test.annotations.generics;
import java.io.Serializable; import java.io.Serializable;
import java.util.Random; import java.util.Random;
import org.hibernate.query.criteria.JpaPath;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.Jira; import org.hibernate.testing.orm.junit.Jira;
import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactory;
@ -79,9 +81,10 @@ public class EmbeddedIdGenericsSuperclassTest {
final CriteriaBuilder cb = session.getCriteriaBuilder(); final CriteriaBuilder cb = session.getCriteriaBuilder();
final CriteriaQuery<Customer> query = cb.createQuery( Customer.class ); final CriteriaQuery<Customer> query = cb.createQuery( Customer.class );
final Root<Customer> root = query.from( Customer.class ); final Root<Customer> root = query.from( Customer.class );
final Path<CustomerId> id = root.get( "id" ); final Path<DomainEntityId> id = root.get( "id" );
assertThat( id ).isNotNull(); assertThat( id.getJavaType() ).isEqualTo( DomainEntityId.class );
assertThat( id.getJavaType() ).isEqualTo( CustomerId.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 ) ); query.select( root ).where( cb.equal( id.get( "someDomainField" ), 1 ) );
final Customer customer = session.createQuery( query ).getSingleResult(); final Customer customer = session.createQuery( query ).getSingleResult();
assertThat( customer ).isNotNull(); assertThat( customer ).isNotNull();
@ -108,9 +111,10 @@ public class EmbeddedIdGenericsSuperclassTest {
final CriteriaBuilder cb = session.getCriteriaBuilder(); final CriteriaBuilder cb = session.getCriteriaBuilder();
final CriteriaQuery<Invoice> query = cb.createQuery( Invoice.class ); final CriteriaQuery<Invoice> query = cb.createQuery( Invoice.class );
final Root<Invoice> root = query.from( Invoice.class ); final Root<Invoice> root = query.from( Invoice.class );
final Path<InvoiceId> id = root.get( "id" ); final Path<DomainEntityId> id = root.get( "id" );
assertThat( id ).isNotNull(); assertThat( id.getJavaType() ).isEqualTo( DomainEntityId.class );
assertThat( id.getJavaType() ).isEqualTo( InvoiceId.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 ) ); query.select( root ).where( cb.equal( id.get( "someOtherDomainField" ), 1 ) );
final Invoice invoice = session.createQuery( query ).getSingleResult(); final Invoice invoice = session.createQuery( query ).getSingleResult();
assertThat( invoice ).isNotNull(); assertThat( invoice ).isNotNull();

View File

@ -6,6 +6,8 @@
*/ */
package org.hibernate.orm.test.annotations.generics; 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.DomainModel;
import org.hibernate.testing.orm.junit.Jira; import org.hibernate.testing.orm.junit.Jira;
import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactory;
@ -35,7 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat;
MultipleEmbeddedGenericsTest.Invoice.class MultipleEmbeddedGenericsTest.Invoice.class
}) })
@SessionFactory @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 { public class MultipleEmbeddedGenericsTest {
@BeforeAll @BeforeAll
public void setUp(SessionFactoryScope scope) { public void setUp(SessionFactoryScope scope) {
@ -75,9 +77,13 @@ public class MultipleEmbeddedGenericsTest {
final Path<CustomerEmbeddableOne> firstEmbedded = root.get( "firstEmbedded" ); final Path<CustomerEmbeddableOne> firstEmbedded = root.get( "firstEmbedded" );
assertThat( firstEmbedded.getJavaType() ).isEqualTo( GenericEmbeddableOne.class ); assertThat( firstEmbedded.getJavaType() ).isEqualTo( GenericEmbeddableOne.class );
assertThat( firstEmbedded.getModel() ).isSameAs( root.getModel().getAttribute( "firstEmbedded" ) ); assertThat( firstEmbedded.getModel() ).isSameAs( root.getModel().getAttribute( "firstEmbedded" ) );
assertThat( ( (JpaPath<?>) firstEmbedded ).getResolvedModel().getBindableJavaType() )
.isEqualTo( CustomerEmbeddableOne.class );
final Path<CustomerEmbeddableTwo> secondEmbedded = root.get( "secondEmbedded" ); final Path<CustomerEmbeddableTwo> secondEmbedded = root.get( "secondEmbedded" );
assertThat( secondEmbedded.getJavaType() ).isEqualTo( GenericEmbeddableTwo.class ); assertThat( secondEmbedded.getJavaType() ).isEqualTo( GenericEmbeddableTwo.class );
assertThat( secondEmbedded.getModel() ).isSameAs( root.getModel().getAttribute( "secondEmbedded" ) ); assertThat( secondEmbedded.getModel() ).isSameAs( root.getModel().getAttribute( "secondEmbedded" ) );
assertThat( ( (JpaPath<?>) secondEmbedded ).getResolvedModel().getBindableJavaType() )
.isEqualTo( CustomerEmbeddableTwo.class );
query.select( root ).where( cb.and( query.select( root ).where( cb.and(
cb.equal( firstEmbedded.get( "genericPropertyA" ), "1" ), cb.equal( firstEmbedded.get( "genericPropertyA" ), "1" ),
cb.equal( secondEmbedded.get( "customerPropertyB" ), 2 ) cb.equal( secondEmbedded.get( "customerPropertyB" ), 2 )
@ -107,9 +113,13 @@ public class MultipleEmbeddedGenericsTest {
final Path<InvoiceEmbeddableOne> firstEmbedded = root.get( "firstEmbedded" ); final Path<InvoiceEmbeddableOne> firstEmbedded = root.get( "firstEmbedded" );
assertThat( firstEmbedded.getJavaType() ).isEqualTo( GenericEmbeddableOne.class ); assertThat( firstEmbedded.getJavaType() ).isEqualTo( GenericEmbeddableOne.class );
assertThat( firstEmbedded.getModel() ).isSameAs( root.getModel().getAttribute( "firstEmbedded" ) ); assertThat( firstEmbedded.getModel() ).isSameAs( root.getModel().getAttribute( "firstEmbedded" ) );
assertThat( ( (JpaPath<?>) firstEmbedded ).getResolvedModel().getBindableJavaType() )
.isEqualTo( InvoiceEmbeddableOne.class );
final Path<InvoiceEmbeddableTwo> secondEmbedded = root.get( "secondEmbedded" ); final Path<InvoiceEmbeddableTwo> secondEmbedded = root.get( "secondEmbedded" );
assertThat( secondEmbedded.getJavaType() ).isEqualTo( GenericEmbeddableTwo.class ); assertThat( secondEmbedded.getJavaType() ).isEqualTo( GenericEmbeddableTwo.class );
assertThat( secondEmbedded.getModel() ).isSameAs( root.getModel().getAttribute( "secondEmbedded" ) ); assertThat( secondEmbedded.getModel() ).isSameAs( root.getModel().getAttribute( "secondEmbedded" ) );
assertThat( ( (JpaPath<?>) secondEmbedded ).getResolvedModel().getBindableJavaType() )
.isEqualTo( InvoiceEmbeddableTwo.class );
query.select( root ).where( cb.and( query.select( root ).where( cb.and(
cb.equal( firstEmbedded.get( "invoicePropertyA" ), 1 ), cb.equal( firstEmbedded.get( "invoicePropertyA" ), 1 ),
cb.equal( secondEmbedded.get( "genericPropertyB" ), "2" ) cb.equal( secondEmbedded.get( "genericPropertyB" ), "2" )