HHH-16238 Correct path model in createSqmPath for SingularAttributeImpl
This commit is contained in:
parent
16c9b1f5b7
commit
e896656bb3
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
);
|
);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
);
|
);
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
);
|
);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
);
|
);
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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" )
|
||||||
|
|
Loading…
Reference in New Issue