HHH-16378 Handle non-embeddable generic attribute paths
This commit is contained in:
parent
b703f23a92
commit
dc87f4bf18
|
@ -23,6 +23,7 @@ import org.hibernate.mapping.Map;
|
|||
import org.hibernate.mapping.OneToMany;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.mapping.SimpleValue;
|
||||
import org.hibernate.mapping.Value;
|
||||
import org.hibernate.metamodel.AttributeClassification;
|
||||
import org.hibernate.metamodel.RepresentationMode;
|
||||
|
@ -36,6 +37,7 @@ import org.hibernate.metamodel.mapping.EntityVersionMapping;
|
|||
import org.hibernate.metamodel.model.domain.AbstractIdentifiableType;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
|
||||
import org.hibernate.metamodel.model.domain.ManagedDomainType;
|
||||
import org.hibernate.metamodel.model.domain.PersistentAttribute;
|
||||
|
@ -116,7 +118,11 @@ public class AttributeFactory {
|
|||
|
||||
if ( attributeMetadata instanceof PluralAttributeMetadata ) {
|
||||
//noinspection rawtypes
|
||||
return PluralAttributeBuilder.build( (PluralAttributeMetadata) attributeMetadata, metadataContext );
|
||||
return PluralAttributeBuilder.build(
|
||||
(PluralAttributeMetadata) attributeMetadata,
|
||||
property.isGeneric(),
|
||||
metadataContext
|
||||
);
|
||||
}
|
||||
|
||||
final SingularAttributeMetadata<X, Y> singularAttributeMetadata = (SingularAttributeMetadata<X, Y>) attributeMetadata;
|
||||
|
@ -221,7 +227,18 @@ public class AttributeFactory {
|
|||
public static <Y> DomainType<Y> determineSimpleType(ValueContext typeContext, MetadataContext context) {
|
||||
switch ( typeContext.getValueClassification() ) {
|
||||
case BASIC: {
|
||||
return context.resolveBasicType( typeContext.getJpaBindableType() );
|
||||
Class returnedClass = typeContext.getJpaBindableType();
|
||||
if ( returnedClass.isAssignableFrom( Object.class ) ) {
|
||||
final SimpleValue simpleValue = (SimpleValue) typeContext.getHibernateValue();
|
||||
if ( simpleValue.getTypeParameters() != null && typeContext.getAttributeMetadata()
|
||||
.getOwnerType() instanceof EntityDomainType ) {
|
||||
// Due to how generics work with Java, the type of generic fields will always
|
||||
// be reported as Object. We need to resolve type based on the actual property
|
||||
// value for basic attributes in entities which specify concrete type parameters.
|
||||
returnedClass = simpleValue.getType().getReturnedClass();
|
||||
}
|
||||
}
|
||||
return context.resolveBasicType( returnedClass );
|
||||
}
|
||||
case ENTITY: {
|
||||
final org.hibernate.type.Type type = typeContext.getHibernateValue().getType();
|
||||
|
|
|
@ -273,7 +273,7 @@ public class MetadataContext {
|
|||
|
||||
applyIdMetadata( safeMapping, jpaMapping );
|
||||
applyVersionAttribute( safeMapping, jpaMapping );
|
||||
applyGenericEmbeddableProperties( safeMapping, jpaMapping );
|
||||
applyGenericProperties( safeMapping, jpaMapping );
|
||||
|
||||
for ( Property property : safeMapping.getDeclaredProperties() ) {
|
||||
if ( property.getValue() == safeMapping.getIdentifierMapper() ) {
|
||||
|
@ -430,16 +430,15 @@ public class MetadataContext {
|
|||
//noinspection unchecked
|
||||
attributeContainer.getInFlightAccess().applyIdAttribute( idAttribute );
|
||||
}
|
||||
else if ( persistentClass.getIdentifier() instanceof Component
|
||||
&& persistentClass.getIdentifierProperty() != getSuperclassIdentifier( persistentClass ) ) {
|
||||
// If the identifier is a generic component, we have to call buildIdAttribute anyway,
|
||||
// as this will create and register the EmbeddableType for the subtype
|
||||
final SingularPersistentAttribute<?, Object> concreteEmbeddable = attributeFactory.buildIdAttribute(
|
||||
final Property superclassIdentifier = getMappedSuperclassIdentifier( persistentClass );
|
||||
if ( superclassIdentifier != null && superclassIdentifier.isGeneric() ) {
|
||||
// If the superclass identifier is generic we have to build the attribute to register the concrete type
|
||||
final SingularPersistentAttribute<?, Object> concreteIdentifier = attributeFactory.buildIdAttribute(
|
||||
identifiableType,
|
||||
persistentClass.getIdentifierProperty()
|
||||
);
|
||||
//noinspection unchecked
|
||||
attributeContainer.getInFlightAccess().addConcreteEmbeddableAttribute( concreteEmbeddable );
|
||||
attributeContainer.getInFlightAccess().addConcreteGenericAttribute( concreteIdentifier );
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -489,30 +488,14 @@ public class MetadataContext {
|
|||
}
|
||||
}
|
||||
|
||||
private Property getSuperclassIdentifier(PersistentClass persistentClass) {
|
||||
final Property declaredIdentifierProperty = persistentClass.getDeclaredIdentifierProperty();
|
||||
if ( declaredIdentifierProperty != null ) {
|
||||
return declaredIdentifierProperty;
|
||||
}
|
||||
if ( persistentClass.getSuperMappedSuperclass() != null ) {
|
||||
return getSuperclassIdentifier( persistentClass.getSuperMappedSuperclass() );
|
||||
}
|
||||
else if ( persistentClass.getSuperclass() != null ) {
|
||||
return getSuperclassIdentifier( persistentClass.getSuperclass() );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Property getSuperclassIdentifier(MappedSuperclass persistentClass) {
|
||||
final Property declaredIdentifierProperty = persistentClass.getDeclaredIdentifierProperty();
|
||||
if ( declaredIdentifierProperty != null ) {
|
||||
return declaredIdentifierProperty;
|
||||
}
|
||||
if ( persistentClass.getSuperMappedSuperclass() != null ) {
|
||||
return getSuperclassIdentifier( persistentClass.getSuperMappedSuperclass() );
|
||||
}
|
||||
else if ( persistentClass.getSuperPersistentClass() != null ) {
|
||||
return getSuperclassIdentifier( persistentClass.getSuperPersistentClass() );
|
||||
private Property getMappedSuperclassIdentifier(PersistentClass persistentClass) {
|
||||
MappedSuperclass mappedSuperclass = getMappedSuperclass( persistentClass );
|
||||
while ( mappedSuperclass != null ) {
|
||||
final Property declaredIdentifierProperty = mappedSuperclass.getDeclaredIdentifierProperty();
|
||||
if ( declaredIdentifierProperty != null ) {
|
||||
return declaredIdentifierProperty;
|
||||
}
|
||||
mappedSuperclass = getMappedSuperclass( mappedSuperclass );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -573,20 +556,15 @@ public class MetadataContext {
|
|||
}
|
||||
}
|
||||
|
||||
private <X> void applyGenericEmbeddableProperties(
|
||||
PersistentClass persistentClass,
|
||||
EntityDomainType<X> entityType) {
|
||||
private <X> void applyGenericProperties(PersistentClass persistentClass, EntityDomainType<X> entityType) {
|
||||
MappedSuperclass mappedSuperclass = getMappedSuperclass( persistentClass );
|
||||
while ( mappedSuperclass != null ) {
|
||||
for ( Property superclassProperty : mappedSuperclass.getDeclaredProperties() ) {
|
||||
if ( superclassProperty.isGeneric() && superclassProperty.isComposite() ) {
|
||||
if ( superclassProperty.isGeneric() ) {
|
||||
final Property property = persistentClass.getProperty( superclassProperty.getName() );
|
||||
final SingularPersistentAttribute<X, ?> attribute = (SingularPersistentAttribute<X, ?>) attributeFactory.buildAttribute(
|
||||
entityType,
|
||||
property
|
||||
);
|
||||
//noinspection unchecked rawtypes
|
||||
( (AttributeContainer) entityType ).getInFlightAccess().addConcreteEmbeddableAttribute( attribute );
|
||||
final PersistentAttribute<X, ?> attribute = attributeFactory.buildAttribute( entityType, property );
|
||||
//noinspection unchecked
|
||||
( (AttributeContainer<X>) entityType ).getInFlightAccess().addConcreteGenericAttribute( attribute );
|
||||
}
|
||||
}
|
||||
mappedSuperclass = getMappedSuperclass( mappedSuperclass );
|
||||
|
|
|
@ -416,7 +416,8 @@ public abstract class AbstractIdentifiableType<J>
|
|||
EntityIdentifierMapping.ROLE_LOCAL_NAME,
|
||||
(SqmPathSource) id,
|
||||
(BasicDomainType<?>) type,
|
||||
Bindable.BindableType.SINGULAR_ATTRIBUTE
|
||||
Bindable.BindableType.SINGULAR_ATTRIBUTE,
|
||||
id.isGeneric()
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -56,7 +56,7 @@ public abstract class AbstractManagedType<J>
|
|||
|
||||
private final Map<String, SingularPersistentAttribute<J, ?>> declaredSingularAttributes = new LinkedHashMap<>();
|
||||
private volatile Map<String, PluralPersistentAttribute<J, ?, ?>> declaredPluralAttributes ;
|
||||
private volatile Map<String, SingularPersistentAttribute<J, ?>> declaredConcreteEmbeddedAttributes;
|
||||
private volatile Map<String, PersistentAttribute<J, ?>> declaredConcreteGenericAttributes;
|
||||
|
||||
private final List<ManagedDomainType> subTypes = new ArrayList<>();
|
||||
|
||||
|
@ -466,20 +466,20 @@ public abstract class AbstractManagedType<J>
|
|||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Generic Embeddable attributes
|
||||
// Generic attributes
|
||||
|
||||
@Override
|
||||
public SingularPersistentAttribute<? super J, ?> findConcreteEmbeddableAttribute(String name) {
|
||||
SingularPersistentAttribute<? super J, ?> attribute = findDeclaredConcreteEmbeddableAttribute( name );
|
||||
public PersistentAttribute<? super J, ?> findConcreteGenericAttribute(String name) {
|
||||
PersistentAttribute<? super J, ?> attribute = findDeclaredConcreteGenericAttribute( name );
|
||||
if ( attribute == null && getSuperType() != null ) {
|
||||
attribute = getSuperType().findDeclaredConcreteEmbeddableAttribute( name );
|
||||
attribute = getSuperType().findDeclaredConcreteGenericAttribute( name );
|
||||
}
|
||||
return attribute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingularPersistentAttribute<? super J, ?> findDeclaredConcreteEmbeddableAttribute(String name) {
|
||||
return declaredConcreteEmbeddedAttributes == null ? null : declaredConcreteEmbeddedAttributes.get( name );
|
||||
public PersistentAttribute<? super J, ?> findDeclaredConcreteGenericAttribute(String name) {
|
||||
return declaredConcreteGenericAttributes == null ? null : declaredConcreteGenericAttributes.get( name );
|
||||
}
|
||||
|
||||
|
||||
|
@ -760,11 +760,11 @@ public abstract class AbstractManagedType<J>
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addConcreteEmbeddableAttribute(SingularPersistentAttribute<J, ?> attribute) {
|
||||
if ( declaredConcreteEmbeddedAttributes == null ) {
|
||||
declaredConcreteEmbeddedAttributes = new HashMap<>();
|
||||
public void addConcreteGenericAttribute(PersistentAttribute<J, ?> attribute) {
|
||||
if ( declaredConcreteGenericAttributes == null ) {
|
||||
declaredConcreteGenericAttributes = new HashMap<>();
|
||||
}
|
||||
declaredConcreteEmbeddedAttributes.put( attribute.getName(), attribute );
|
||||
declaredConcreteGenericAttributes.put( attribute.getName(), attribute );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -59,12 +59,12 @@ public interface ManagedDomainType<J> extends SqmExpressible<J>, DomainType<J>,
|
|||
|
||||
SingularPersistentAttribute<? super J,?> findSingularAttribute(String name);
|
||||
PluralPersistentAttribute<? super J, ?,?> findPluralAttribute(String name);
|
||||
SingularPersistentAttribute<? super J, ?> findConcreteEmbeddableAttribute(String name);
|
||||
PersistentAttribute<? super J, ?> findConcreteGenericAttribute(String name);
|
||||
|
||||
PersistentAttribute<J,?> findDeclaredAttribute(String name);
|
||||
SingularPersistentAttribute<? super J, ?> findDeclaredSingularAttribute(String name);
|
||||
PluralPersistentAttribute<? super J, ?, ?> findDeclaredPluralAttribute(String name);
|
||||
SingularPersistentAttribute<? super J, ?> findDeclaredConcreteEmbeddableAttribute(String name);
|
||||
PersistentAttribute<? super J, ?> findDeclaredConcreteGenericAttribute(String name);
|
||||
|
||||
SubGraphImplementor<J> makeSubGraph();
|
||||
<S extends J> SubGraphImplementor<S> makeSubGraph(Class<S> subClassType);
|
||||
|
|
|
@ -54,7 +54,8 @@ public abstract class AbstractPluralAttribute<D, C, E>
|
|||
this.elementPathSource = SqmMappingModelHelper.resolveSqmPathSource(
|
||||
CollectionPart.Nature.ELEMENT.getName(),
|
||||
builder.getValueType(),
|
||||
BindableType.PLURAL_ATTRIBUTE
|
||||
BindableType.PLURAL_ATTRIBUTE,
|
||||
builder.isGeneric()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -83,7 +84,7 @@ public abstract class AbstractPluralAttribute<D, C, E>
|
|||
|
||||
@Override
|
||||
public SqmPathSource<?> getIntermediatePathSource(SqmPathSource<?> pathSource) {
|
||||
return pathSource == elementPathSource ? null : elementPathSource;
|
||||
return pathSource.getPathName().equals( elementPathSource.getPathName() ) ? null : elementPathSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -154,4 +155,9 @@ public abstract class AbstractPluralAttribute<D, C, E>
|
|||
lhs.nodeBuilder()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGeneric() {
|
||||
return elementPathSource.isGeneric();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,8 @@ public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
|
|||
"id",
|
||||
null,
|
||||
(BasicDomainType<?>) domainType.getKeyType(),
|
||||
SINGULAR_ATTRIBUTE
|
||||
SINGULAR_ATTRIBUTE,
|
||||
false
|
||||
);
|
||||
discriminatorPathSource = new AnyDiscriminatorSqmPathSource<>(
|
||||
localPathName,
|
||||
|
|
|
@ -66,7 +66,7 @@ public interface AttributeContainer<J> {
|
|||
);
|
||||
}
|
||||
|
||||
default void addConcreteEmbeddableAttribute(SingularPersistentAttribute<J, ?> idAttribute) {
|
||||
default void addConcreteGenericAttribute(PersistentAttribute<J, ?> idAttribute) {
|
||||
throw new UnsupportedMappingException(
|
||||
"AttributeContainer [" + getClass().getName() + "] does not generic embeddables"
|
||||
);
|
||||
|
|
|
@ -19,13 +19,16 @@ import org.hibernate.query.sqm.tree.domain.SqmPath;
|
|||
public class BasicSqmPathSource<J>
|
||||
extends AbstractSqmPathSource<J>
|
||||
implements ReturnableType<J> {
|
||||
private final boolean isGeneric;
|
||||
|
||||
public BasicSqmPathSource(
|
||||
String localPathName,
|
||||
SqmPathSource<J> pathModel,
|
||||
BasicDomainType<J> domainType,
|
||||
BindableType jpaBindableType) {
|
||||
BindableType jpaBindableType,
|
||||
boolean isGeneric) {
|
||||
super( localPathName, pathModel, domainType, jpaBindableType );
|
||||
this.isGeneric = isGeneric;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,6 +69,11 @@ public class BasicSqmPathSource<J>
|
|||
return getExpressibleJavaType().getJavaTypeClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGeneric() {
|
||||
return isGeneric;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BasicSqmPathSource(" +
|
||||
|
|
|
@ -21,12 +21,16 @@ import org.hibernate.query.sqm.tree.from.SqmFrom;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class EntitySqmPathSource<J> extends AbstractSqmPathSource<J> implements SqmJoinable<Object, J> {
|
||||
private final boolean isGeneric;
|
||||
|
||||
public EntitySqmPathSource(
|
||||
String localPathName,
|
||||
SqmPathSource<J> pathModel,
|
||||
EntityDomainType<J> domainType,
|
||||
BindableType jpaBindableType) {
|
||||
BindableType jpaBindableType,
|
||||
boolean isGeneric) {
|
||||
super( localPathName, pathModel, domainType, jpaBindableType );
|
||||
this.isGeneric = isGeneric;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -41,6 +45,11 @@ public class EntitySqmPathSource<J> extends AbstractSqmPathSource<J> implements
|
|||
return sqmPathType.findSubPathSource( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGeneric() {
|
||||
return isGeneric;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
|
||||
final NavigablePath navigablePath;
|
||||
|
|
|
@ -31,7 +31,8 @@ class ListAttributeImpl<X, E> extends AbstractPluralAttribute<X, List<E>, E> imp
|
|||
//noinspection unchecked
|
||||
this.indexPathSource = (SqmPathSource<Integer>) SqmMappingModelHelper.resolveSqmKeyPathSource(
|
||||
builder.getListIndexOrMapKeyType(),
|
||||
BindableType.PLURAL_ATTRIBUTE
|
||||
BindableType.PLURAL_ATTRIBUTE,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -61,7 +62,9 @@ class ListAttributeImpl<X, E> extends AbstractPluralAttribute<X, List<E>, E> imp
|
|||
|
||||
@Override
|
||||
public SqmPathSource<?> getIntermediatePathSource(SqmPathSource<?> pathSource) {
|
||||
return pathSource == getElementPathSource() || pathSource == indexPathSource ? null : getElementPathSource();
|
||||
final String pathName = pathSource.getPathName();
|
||||
return pathName.equals( getElementPathSource().getPathName() )
|
||||
|| pathName.equals( indexPathSource.getPathName() ) ? null : getElementPathSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -31,7 +31,8 @@ class MapAttributeImpl<X, K, V> extends AbstractPluralAttribute<X, Map<K, V>, V>
|
|||
|
||||
this.keyPathSource = SqmMappingModelHelper.resolveSqmKeyPathSource(
|
||||
xceBuilder.getListIndexOrMapKeyType(),
|
||||
BindableType.PLURAL_ATTRIBUTE
|
||||
BindableType.PLURAL_ATTRIBUTE,
|
||||
xceBuilder.isGeneric()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -71,7 +72,9 @@ class MapAttributeImpl<X, K, V> extends AbstractPluralAttribute<X, Map<K, V>, V>
|
|||
|
||||
@Override
|
||||
public SqmPathSource<?> getIntermediatePathSource(SqmPathSource<?> pathSource) {
|
||||
return pathSource == getElementPathSource() || pathSource == keyPathSource ? null : getElementPathSource();
|
||||
final String pathName = pathSource.getPathName();
|
||||
return pathName.equals( getElementPathSource().getPathName() )
|
||||
|| pathName.equals( keyPathSource.getPathName() ) ? null : getElementPathSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -32,6 +32,7 @@ import static org.hibernate.metamodel.internal.AttributeFactory.determineSimpleT
|
|||
*/
|
||||
public class PluralAttributeBuilder<D, C, E, K> {
|
||||
private final JavaType<C> collectionJtd;
|
||||
private boolean isGeneric;
|
||||
|
||||
private final AttributeClassification attributeClassification;
|
||||
private final CollectionClassification collectionClassification;
|
||||
|
@ -46,6 +47,7 @@ public class PluralAttributeBuilder<D, C, E, K> {
|
|||
|
||||
public PluralAttributeBuilder(
|
||||
JavaType<C> collectionJtd,
|
||||
boolean isGeneric,
|
||||
AttributeClassification attributeClassification,
|
||||
CollectionClassification collectionClassification,
|
||||
DomainType<E> elementType,
|
||||
|
@ -54,6 +56,7 @@ public class PluralAttributeBuilder<D, C, E, K> {
|
|||
Property property,
|
||||
Member member) {
|
||||
this.collectionJtd = collectionJtd;
|
||||
this.isGeneric = isGeneric;
|
||||
this.attributeClassification = attributeClassification;
|
||||
this.collectionClassification = collectionClassification;
|
||||
this.elementType = elementType;
|
||||
|
@ -66,6 +69,7 @@ public class PluralAttributeBuilder<D, C, E, K> {
|
|||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public static <Y, X> PersistentAttribute<X, Y> build(
|
||||
PluralAttributeMetadata<?,Y,?> attributeMetadata,
|
||||
boolean isGeneric,
|
||||
MetadataContext metadataContext) {
|
||||
|
||||
final JavaType<Y> attributeJtd = metadataContext.getTypeConfiguration()
|
||||
|
@ -74,6 +78,7 @@ public class PluralAttributeBuilder<D, C, E, K> {
|
|||
|
||||
final PluralAttributeBuilder builder = new PluralAttributeBuilder(
|
||||
attributeJtd,
|
||||
isGeneric,
|
||||
attributeMetadata.getAttributeClassification(),
|
||||
attributeMetadata.getCollectionClassification(),
|
||||
AttributeFactory.determineSimpleType(
|
||||
|
@ -155,6 +160,10 @@ public class PluralAttributeBuilder<D, C, E, K> {
|
|||
return collectionJtd;
|
||||
}
|
||||
|
||||
public boolean isGeneric() {
|
||||
return isGeneric;
|
||||
}
|
||||
|
||||
public DomainType<E> getValueType() {
|
||||
return elementType;
|
||||
}
|
||||
|
|
|
@ -45,8 +45,7 @@ public interface JpaPath<T> extends JpaExpression<T>, Path<T> {
|
|||
<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
|
||||
* Get this path's actual resolved model, i.e. the concrete type for generic attributes.
|
||||
*/
|
||||
SqmPathSource<?> getResolvedModel();
|
||||
|
||||
|
|
|
@ -66,19 +66,22 @@ public class SqmMappingModelHelper {
|
|||
|
||||
public static <J> SqmPathSource<J> resolveSqmKeyPathSource(
|
||||
DomainType<J> valueDomainType,
|
||||
Bindable.BindableType jpaBindableType) {
|
||||
Bindable.BindableType jpaBindableType,
|
||||
boolean isGeneric) {
|
||||
return resolveSqmPathSource(
|
||||
CollectionPart.Nature.INDEX.getName(),
|
||||
valueDomainType,
|
||||
jpaBindableType
|
||||
jpaBindableType,
|
||||
isGeneric
|
||||
);
|
||||
}
|
||||
|
||||
public static <J> SqmPathSource<J> resolveSqmPathSource(
|
||||
String name,
|
||||
DomainType<J> valueDomainType,
|
||||
Bindable.BindableType jpaBindableType) {
|
||||
return resolveSqmPathSource( name, null, valueDomainType, jpaBindableType, false );
|
||||
Bindable.BindableType jpaBindableType,
|
||||
boolean isGeneric) {
|
||||
return resolveSqmPathSource( name, null, valueDomainType, jpaBindableType, isGeneric );
|
||||
}
|
||||
|
||||
public static <J> SqmPathSource<J> resolveSqmPathSource(
|
||||
|
@ -93,7 +96,8 @@ public class SqmMappingModelHelper {
|
|||
name,
|
||||
pathModel,
|
||||
(BasicDomainType<J>) valueDomainType,
|
||||
jpaBindableType
|
||||
jpaBindableType,
|
||||
isGeneric
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -121,7 +125,8 @@ public class SqmMappingModelHelper {
|
|||
name,
|
||||
pathModel,
|
||||
(EntityDomainType<J>) valueDomainType,
|
||||
jpaBindableType
|
||||
jpaBindableType,
|
||||
isGeneric
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,9 @@ import java.util.Map;
|
|||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.metamodel.model.domain.ManagedDomainType;
|
||||
import org.hibernate.metamodel.model.domain.PersistentAttribute;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
|
@ -140,6 +142,17 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
|
|||
|
||||
@Override
|
||||
public SqmPathSource<?> getResolvedModel() {
|
||||
final DomainType<?> lhsType;
|
||||
final SqmPathSource<T> pathSource = getReferencedPathSource();
|
||||
if ( pathSource.isGeneric() && ( lhsType = getLhs().getReferencedPathSource()
|
||||
.getSqmPathType() ) instanceof ManagedDomainType ) {
|
||||
final PersistentAttribute<?, ?> concreteAttribute = ( (ManagedDomainType<?>) lhsType ).findConcreteGenericAttribute(
|
||||
pathSource.getPathName()
|
||||
);
|
||||
if ( concreteAttribute != null ) {
|
||||
return (SqmPathSource<?>) concreteAttribute;
|
||||
}
|
||||
}
|
||||
return getModel();
|
||||
}
|
||||
|
||||
|
@ -163,9 +176,7 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
|
|||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public SqmPath<?> get(String attributeName) {
|
||||
|
||||
final SqmPathSource<?> subNavigable = getReferencedPathSource().getSubPathSource( attributeName );
|
||||
|
||||
final SqmPathSource<?> subNavigable = getResolvedModel().getSubPathSource( attributeName );
|
||||
return resolvePath( attributeName, subNavigable );
|
||||
}
|
||||
|
||||
|
|
|
@ -90,6 +90,11 @@ public class SqmCteRoot<T> extends SqmRoot<T> implements JpaRoot<T> {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPathSource<?> getResolvedModel() {
|
||||
return getReferencedPathSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmCorrelatedRoot<T> createCorrelation() {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
|
@ -92,6 +92,11 @@ public class SqmDerivedRoot<T> extends SqmRoot<T> implements JpaDerivedRoot<T> {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPathSource<?> getResolvedModel() {
|
||||
return getReferencedPathSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmCorrelatedRoot<T> createCorrelation() {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
|
@ -6,12 +6,8 @@
|
|||
*/
|
||||
package org.hibernate.query.sqm.tree.domain;
|
||||
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.metamodel.model.domain.ManagedDomainType;
|
||||
import org.hibernate.metamodel.model.domain.internal.CompositeSqmPathSource;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.query.PathException;
|
||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
|
@ -19,6 +15,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker;
|
|||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
||||
/**
|
||||
|
@ -80,29 +77,6 @@ public class SqmEmbeddedValuedSimplePath<T>
|
|||
return sqmPath;
|
||||
}
|
||||
|
||||
@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<T> pathSource = getReferencedPathSource();
|
||||
if ( pathSource.isGeneric() && ( lhsType = getLhs().getReferencedPathSource()
|
||||
.getSqmPathType() ) instanceof ManagedDomainType ) {
|
||||
//noinspection rawtypes
|
||||
final SqmPathSource<?> concreteEmbeddable = ( (ManagedDomainType) lhsType ).findConcreteEmbeddableAttribute(
|
||||
pathSource.getPathName()
|
||||
);
|
||||
if ( concreteEmbeddable != null ) {
|
||||
return concreteEmbeddable;
|
||||
}
|
||||
}
|
||||
return getModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitEmbeddableValuedPath( this );
|
||||
|
|
|
@ -210,7 +210,7 @@ public class SqmPolymorphicRootDescriptor<T> implements EntityDomainType<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SingularPersistentAttribute<? super T, ?> findConcreteEmbeddableAttribute(String name) {
|
||||
public PersistentAttribute<? super T, ?> findConcreteGenericAttribute(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -230,7 +230,7 @@ public class SqmPolymorphicRootDescriptor<T> implements EntityDomainType<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SingularPersistentAttribute<? super T, ?> findDeclaredConcreteEmbeddableAttribute(String name) {
|
||||
public PersistentAttribute<? super T, ?> findDeclaredConcreteGenericAttribute(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue