HHH-16241 Add relational java type to SqmExpressible for function argument validation

This commit is contained in:
Marco Belladelli 2023-03-09 10:36:44 +01:00 committed by Christian Beikov
parent 0119236d8d
commit ca6c44937e
8 changed files with 57 additions and 5 deletions

View File

@ -13,6 +13,7 @@ import java.lang.reflect.ParameterizedType;
import org.hibernate.AssertionFailure;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
import org.hibernate.internal.EntityManagerMessageLogger;
import org.hibernate.internal.HEMLogging;
import org.hibernate.mapping.Any;
@ -28,6 +29,7 @@ import org.hibernate.mapping.Value;
import org.hibernate.metamodel.AttributeClassification;
import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.metamodel.UnsupportedMappingException;
import org.hibernate.metamodel.ValueClassification;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.CompositeIdentifierMapping;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
@ -125,13 +127,19 @@ public class AttributeFactory {
);
}
final SingularAttributeMetadata<X, Y> singularAttributeMetadata = (SingularAttributeMetadata<X, Y>) attributeMetadata;
final DomainType<Y> metaModelType = determineSimpleType( singularAttributeMetadata.getValueContext(), metadataContext );
final ValueContext valueContext = ( (SingularAttributeMetadata<X, Y>) attributeMetadata ).getValueContext();
final DomainType<Y> metaModelType = determineSimpleType( valueContext, metadataContext );
final JavaType<?> relationalJavaType = determineRelationalJavaType(
valueContext,
metaModelType,
metadataContext
);
return new SingularAttributeImpl<>(
ownerType,
attributeMetadata.getName(),
attributeMetadata.getAttributeClassification(),
metaModelType,
relationalJavaType,
attributeMetadata.getMember(),
false,
false,
@ -329,6 +337,21 @@ public class AttributeFactory {
}
}
private static JavaType<?> determineRelationalJavaType(
ValueContext typeContext,
DomainType<?> metaModelType,
MetadataContext context) {
if ( typeContext.getValueClassification() == ValueClassification.BASIC ) {
final ConverterDescriptor descriptor = ( (SimpleValue) typeContext.getHibernateValue() ).getJpaAttributeConverterDescriptor();
if ( descriptor != null ) {
return context.getJavaTypeRegistry().resolveDescriptor(
descriptor.getRelationalValueResolvedType().getErasedType()
);
}
}
return metaModelType.getExpressibleJavaType();
}
private static EntityPersister getDeclaringEntity(
AbstractIdentifiableType<?> ownerType,
MetadataContext metadataContext) {

View File

@ -416,6 +416,7 @@ public abstract class AbstractIdentifiableType<J>
EntityIdentifierMapping.ROLE_LOCAL_NAME,
(SqmPathSource) id,
(BasicDomainType<?>) type,
type.getExpressibleJavaType(),
Bindable.BindableType.SINGULAR_ATTRIBUTE,
id.isGeneric()
);

View File

@ -33,6 +33,7 @@ public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
"id",
null,
(BasicDomainType<?>) domainType.getKeyType(),
domainType.getKeyType().getExpressibleJavaType(),
SINGULAR_ATTRIBUTE,
false
);

View File

@ -8,10 +8,11 @@ package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.query.ReturnableType;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.spi.NavigablePath;
import org.hibernate.type.descriptor.java.JavaType;
/**
* @author Steve Ebersole
@ -19,15 +20,18 @@ import org.hibernate.query.sqm.tree.domain.SqmPath;
public class BasicSqmPathSource<J>
extends AbstractSqmPathSource<J>
implements ReturnableType<J> {
private final JavaType<?> relationalJavaType;
private final boolean isGeneric;
public BasicSqmPathSource(
String localPathName,
SqmPathSource<J> pathModel,
BasicDomainType<J> domainType,
JavaType<?> relationalJavaType,
BindableType jpaBindableType,
boolean isGeneric) {
super( localPathName, pathModel, domainType, jpaBindableType );
this.relationalJavaType = relationalJavaType;
this.isGeneric = isGeneric;
}
@ -69,6 +73,11 @@ public class BasicSqmPathSource<J>
return getExpressibleJavaType().getJavaTypeClass();
}
@Override
public JavaType<?> getRelationalJavaType() {
return relationalJavaType;
}
@Override
public boolean isGeneric() {
return isGeneric;

View File

@ -55,6 +55,7 @@ public class SingularAttributeImpl<D,J>
String name,
AttributeClassification attributeClassification,
DomainType<J> attributeType,
JavaType<?> relationalJavaType,
Member member,
boolean isIdentifier,
boolean isVersion,
@ -79,6 +80,7 @@ public class SingularAttributeImpl<D,J>
name,
this,
attributeType,
relationalJavaType,
BindableType.SINGULAR_ATTRIBUTE,
isGeneric
);
@ -174,6 +176,7 @@ public class SingularAttributeImpl<D,J>
name,
attributeClassification,
attributeType,
attributeType.getExpressibleJavaType(),
member,
true,
false,
@ -215,6 +218,7 @@ public class SingularAttributeImpl<D,J>
name,
attributeClassification,
attributeType,
attributeType.getExpressibleJavaType(),
member,
false,
true,

View File

@ -25,6 +25,10 @@ public interface SqmExpressible<J> extends BindableType<J> {
*/
JavaType<J> getExpressibleJavaType();
default JavaType<?> getRelationalJavaType() {
return getExpressibleJavaType();
}
@Override
default boolean isInstance(J value) {
return getExpressibleJavaType().isInstance( value );

View File

@ -38,6 +38,7 @@ import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
import org.hibernate.spi.NavigablePath;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.JavaType;
import jakarta.persistence.metamodel.Bindable;
@ -81,13 +82,21 @@ public class SqmMappingModelHelper {
DomainType<J> valueDomainType,
Bindable.BindableType jpaBindableType,
boolean isGeneric) {
return resolveSqmPathSource( name, null, valueDomainType, jpaBindableType, isGeneric );
return resolveSqmPathSource(
name,
null,
valueDomainType,
valueDomainType.getExpressibleJavaType(),
jpaBindableType,
isGeneric
);
}
public static <J> SqmPathSource<J> resolveSqmPathSource(
String name,
SqmPathSource<J> pathModel,
DomainType<J> valueDomainType,
JavaType<?> relationalJavaType,
Bindable.BindableType jpaBindableType,
boolean isGeneric) {
@ -96,6 +105,7 @@ public class SqmMappingModelHelper {
name,
pathModel,
(BasicDomainType<J>) valueDomainType,
relationalJavaType,
jpaBindableType,
isGeneric
);

View File

@ -91,7 +91,7 @@ public class ArgumentTypesValidator implements ArgumentsValidator {
SqmExpressible<?> nodeType = argument.getNodeType();
FunctionParameterType type = count < types.length ? types[count++] : types[types.length - 1];
if ( nodeType != null ) {
JavaType<?> javaType = nodeType.getExpressibleJavaType();
JavaType<?> javaType = nodeType.getRelationalJavaType();
if (javaType != null) {
try {
checkType(