HHH-15428 Fix handling of converters by moving them to JdbcMapping

This commit is contained in:
Christian Beikov 2022-08-02 23:42:56 +02:00
parent 4674f689aa
commit 7b6df34519
145 changed files with 2184 additions and 1418 deletions

View File

@ -17,6 +17,7 @@ import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
@ -25,6 +26,7 @@ import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.isOneOf;
/**
@ -60,32 +62,35 @@ public class BooleanMappingTests {
{
final BasicAttributeMapping convertedYesNo = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("convertedYesNo");
final JdbcMapping jdbcMapping = convertedYesNo.getJdbcMapping();
assertThat(jdbcMapping.getJavaTypeDescriptor().getJavaType(), equalTo(Character.class));
assertThat( jdbcMapping, instanceOf( ConvertedBasicTypeImpl.class ) );
assertThat( jdbcMapping.getJdbcJavaType().getJavaType(), equalTo( Character.class ) );
assertThat(
jdbcMapping.getJdbcType().getJdbcTypeCode(),
// could be NCHAR if nationalization is globally enabled
isOneOf(Types.CHAR, Types.NCHAR)
isOneOf( Types.CHAR, Types.NCHAR )
);
}
{
final BasicAttributeMapping convertedTrueFalse = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("convertedTrueFalse");
final JdbcMapping jdbcMapping = convertedTrueFalse.getJdbcMapping();
assertThat(jdbcMapping.getJavaTypeDescriptor().getJavaType(), equalTo(Character.class));
assertThat( jdbcMapping, instanceOf( ConvertedBasicTypeImpl.class ) );
assertThat( jdbcMapping.getJdbcJavaType().getJavaType(), equalTo( Character.class ) );
assertThat(
jdbcMapping.getJdbcType().getJdbcTypeCode(),
// could be NCHAR if nationalization is globally enabled
isOneOf(Types.CHAR, Types.NCHAR)
isOneOf( Types.CHAR, Types.NCHAR )
);
}
{
final BasicAttributeMapping convertedNumeric = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("convertedNumeric");
final JdbcMapping jdbcMapping = convertedNumeric.getJdbcMapping();
assertThat(jdbcMapping.getJavaTypeDescriptor().getJavaType(), equalTo(Integer.class));
assertThat( jdbcMapping, instanceOf( ConvertedBasicTypeImpl.class ) );
assertThat( jdbcMapping.getJdbcJavaType().getJavaType(), equalTo( Integer.class ) );
assertThat(
jdbcMapping.getJdbcType().getJdbcTypeCode(),
equalTo(Types.INTEGER)
equalTo( Types.INTEGER )
);
}

View File

@ -17,12 +17,15 @@ import jakarta.persistence.Table;
import org.hibernate.annotations.Immutable;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
@ -46,18 +49,25 @@ public class BitSetConverterImmutableTests {
@Test
public void verifyMappings(SessionFactoryScope scope) {
final SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
final MappingMetamodelImplementor mappingMetamodel = scope.getSessionFactory()
.getRuntimeMetamodels()
final MappingMetamodelImplementor mappingMetamodel = sessionFactory.getRuntimeMetamodels()
.getMappingMetamodel();
final EntityPersister entityDescriptor = mappingMetamodel.findEntityDescriptor(Product.class);
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("bitSet");
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
assertThat( attributeMapping.getJavaType().getJavaTypeClass(), equalTo( BitSet.class));
assertThat( attributeMapping.getJavaType().getJavaTypeClass(), equalTo( BitSet.class ) );
assertThat(attributeMapping.getValueConverter(), instanceOf(JpaAttributeConverter.class));
final JpaAttributeConverter converter = (JpaAttributeConverter) attributeMapping.getValueConverter();
assertThat(converter.getConverterBean().getBeanClass(), equalTo(BitSetConverter.class));
assertThat( jdbcMapping, instanceOf( ConvertedBasicTypeImpl.class ) );
final BasicValueConverter<?, ?> converter = jdbcMapping.getValueConverter();
assertThat(
converter,
instanceOf( JpaAttributeConverter.class )
);
assertThat(
( (JpaAttributeConverter<?, ?>) converter ).getConverterBean().getBeanClass(),
equalTo( BitSetConverter.class )
);
Assertions.assertThat(attributeMapping.getExposedMutabilityPlan()).isNotInstanceOf(BitSetMutabilityPlan.class);
Assertions.assertThat(attributeMapping.getExposedMutabilityPlan()).isInstanceOf(ImmutableMutabilityPlan.class);
@ -67,11 +77,11 @@ public class BitSetConverterImmutableTests {
Assertions.assertThat(((MutabilityPlan) attributeMapping.getExposedMutabilityPlan()).deepCopy(sample)).isSameAs(sample);
assertThat(
attributeMapping.getJdbcMapping().getJdbcType().getJdbcTypeCode(),
jdbcMapping.getJdbcType().getJdbcTypeCode(),
isOneOf(Types.VARCHAR, Types.NVARCHAR)
);
assertThat(attributeMapping.getJdbcMapping().getJavaTypeDescriptor().getJavaTypeClass(), equalTo(String.class));
assertThat(converter.getRelationalJavaType().getJavaTypeClass(), equalTo(String.class));
}
@Table(name = "products")

View File

@ -17,10 +17,13 @@ import jakarta.persistence.Table;
import org.hibernate.annotations.Mutability;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
@ -51,21 +54,29 @@ public class BitSetConverterMutabilityTests {
final EntityPersister entityDescriptor = mappingMetamodel.findEntityDescriptor(Product.class);
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("bitSet");
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
assertThat( attributeMapping.getJavaType().getJavaTypeClass(), equalTo( BitSet.class));
assertThat( attributeMapping.getJavaType().getJavaTypeClass(), equalTo( BitSet.class ) );
assertThat(attributeMapping.getValueConverter(), instanceOf(JpaAttributeConverter.class));
final JpaAttributeConverter converter = (JpaAttributeConverter) attributeMapping.getValueConverter();
assertThat(converter.getConverterBean().getBeanClass(), equalTo(BitSetConverter.class));
assertThat( jdbcMapping, instanceOf( ConvertedBasicTypeImpl.class ) );
final BasicValueConverter<?, ?> converter = jdbcMapping.getValueConverter();
assertThat(
converter,
instanceOf( JpaAttributeConverter.class )
);
assertThat(
( (JpaAttributeConverter<?, ?>) converter ).getConverterBean().getBeanClass(),
equalTo( BitSetConverter.class )
);
Assertions.assertThat(attributeMapping.getExposedMutabilityPlan()).isInstanceOf(BitSetMutabilityPlan.class);
assertThat(
attributeMapping.getJdbcMapping().getJdbcType().getJdbcTypeCode(),
jdbcMapping.getJdbcType().getJdbcTypeCode(),
isOneOf(Types.VARCHAR, Types.NVARCHAR)
);
assertThat(attributeMapping.getJdbcMapping().getJavaTypeDescriptor().getJavaTypeClass(), equalTo(String.class));
assertThat(converter.getRelationalJavaType().getJavaTypeClass(), equalTo(String.class));
}
@Table(name = "products")

View File

@ -15,10 +15,13 @@ import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
@ -47,21 +50,29 @@ public class BitSetConverterTests {
final EntityPersister entityDescriptor = mappingMetamodel.findEntityDescriptor(Product.class);
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("bitSet");
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
assertThat( attributeMapping.getJavaType().getJavaTypeClass(), equalTo( BitSet.class));
assertThat( attributeMapping.getJavaType().getJavaTypeClass(), equalTo( BitSet.class ) );
assertThat( jdbcMapping, instanceOf( ConvertedBasicTypeImpl.class ) );
final BasicValueConverter<?, ?> converter = jdbcMapping.getValueConverter();
assertThat(
converter,
instanceOf( JpaAttributeConverter.class )
);
assertThat(
( (JpaAttributeConverter<?, ?>) converter ).getConverterBean().getBeanClass(),
equalTo( BitSetConverter.class )
);
assertThat(attributeMapping.getValueConverter(), instanceOf(JpaAttributeConverter.class));
final JpaAttributeConverter converter = (JpaAttributeConverter) attributeMapping.getValueConverter();
assertThat(converter.getConverterBean().getBeanClass(), equalTo(BitSetConverter.class));
Assertions.assertThat(attributeMapping.getExposedMutabilityPlan()).isNotInstanceOf(BitSetMutabilityPlan.class);
Assertions.assertThat( attributeMapping.getExposedMutabilityPlan() )
.isNotInstanceOf( BitSetMutabilityPlan.class );
assertThat(
attributeMapping.getJdbcMapping().getJdbcType().getJdbcTypeCode(),
jdbcMapping.getJdbcType().getJdbcTypeCode(),
isOneOf(Types.VARCHAR, Types.NVARCHAR)
);
assertThat(attributeMapping.getJdbcMapping().getJavaTypeDescriptor().getJavaTypeClass(), equalTo(String.class));
assertThat( converter.getRelationalJavaType().getJavaTypeClass(), equalTo( String.class ) );
}
@Table(name = "products")

View File

@ -46,7 +46,7 @@ public class BitSetImplicitTests {
assertThat( attributeMapping.getJavaType().getJavaTypeClass(), equalTo( BitSet.class));
assertThat(attributeMapping.getValueConverter(), nullValue());
assertThat(attributeMapping.getJdbcMapping().getValueConverter(), nullValue());
assertThat(
attributeMapping.getJdbcMapping().getJdbcType().getJdbcTypeCode(),

View File

@ -48,7 +48,7 @@ public class BitSetJdbcTypeCodeTests {
assertThat( attributeMapping.getJavaType().getJavaTypeClass(), equalTo( BitSet.class));
assertThat(attributeMapping.getValueConverter(), nullValue());
assertThat(attributeMapping.getJdbcMapping().getValueConverter(), nullValue());
assertThat(
attributeMapping.getJdbcMapping().getJdbcType().getJdbcTypeCode(),

View File

@ -47,7 +47,7 @@ public class BitSetJdbcTypeRegistrationTests {
assertThat( attributeMapping.getJavaType().getJavaTypeClass(), equalTo( BitSet.class));
assertThat(attributeMapping.getValueConverter(), nullValue());
assertThat(attributeMapping.getJdbcMapping().getValueConverter(), nullValue());
assertThat(
attributeMapping.getJdbcMapping().getJdbcType().getJdbcTypeCode(),

View File

@ -47,7 +47,7 @@ public class BitSetJdbcTypeTests {
assertThat( attributeMapping.getJavaType().getJavaTypeClass(), equalTo( BitSet.class));
assertThat(attributeMapping.getValueConverter(), nullValue());
assertThat(attributeMapping.getJdbcMapping().getValueConverter(), nullValue());
assertThat(
attributeMapping.getJdbcMapping().getJdbcType().getJdbcTypeCode(),

View File

@ -21,7 +21,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
*/
public class ConvertedBasicTypeResolution<J> implements BasicValue.Resolution<J> {
private final ConvertedBasicType basicType;
private final ValueConverterTypeAdapter adapted;
// private final ValueConverterTypeAdapter adapted;
public ConvertedBasicTypeResolution(
ConvertedBasicType basicType,
@ -30,21 +30,21 @@ public class ConvertedBasicTypeResolution<J> implements BasicValue.Resolution<J>
final BasicValueConverter valueConverter = basicType.getValueConverter();
this.adapted = new ValueConverterTypeAdapter(
valueConverter.getClass().getTypeName(),
valueConverter,
stdIndicators
);
// this.adapted = new ValueConverterTypeAdapter(
// valueConverter.getClass().getTypeName(),
// valueConverter,
// stdIndicators
// );
}
@Override
public BasicType<J> getLegacyResolvedBasicType() {
return adapted;
return basicType;
}
@Override
public JdbcMapping getJdbcMapping() {
return adapted;
return basicType;
}
@Override
@ -59,7 +59,7 @@ public class ConvertedBasicTypeResolution<J> implements BasicValue.Resolution<J>
@Override
public JdbcType getJdbcType() {
return adapted.getJdbcType();
return basicType.getJdbcType();
}
@Override

View File

@ -25,7 +25,6 @@ public class InferredBasicValueResolution<J,T> implements BasicValue.Resolution<
private final MutabilityPlan<J> mutabilityPlan;
private final JdbcMapping jdbcMapping;
private final BasicValueConverter<J,T> valueConverter;
private final BasicType<J> legacyType;
@ -34,7 +33,6 @@ public class InferredBasicValueResolution<J,T> implements BasicValue.Resolution<
JavaType<J> domainJtd,
JavaType<T> relationalJtd,
JdbcType jdbcType,
BasicValueConverter<J,T> valueConverter,
BasicType<J> legacyType,
MutabilityPlan<J> mutabilityPlan) {
this.jdbcMapping = jdbcMapping;
@ -42,7 +40,6 @@ public class InferredBasicValueResolution<J,T> implements BasicValue.Resolution<
this.domainJtd = domainJtd;
this.relationalJtd = relationalJtd;
this.jdbcType = jdbcType;
this.valueConverter = valueConverter;
this.mutabilityPlan = mutabilityPlan == null ? domainJtd.getMutabilityPlan() : mutabilityPlan;
}
@ -73,7 +70,8 @@ public class InferredBasicValueResolution<J,T> implements BasicValue.Resolution<
@Override
public BasicValueConverter<J,T> getValueConverter() {
return valueConverter;
//noinspection unchecked
return (BasicValueConverter<J, T>) jdbcMapping.getValueConverter();
}
@Override

View File

@ -156,16 +156,6 @@ public class InferredBasicValueResolver {
legacyType = jdbcMapping;
}
else if ( explicitJdbcType != null ) {
// we also have an explicit JdbcType
jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(
reflectedJtd,
explicitJdbcType
);
legacyType = jdbcMapping;
}
else {
// see if there is a registered BasicType for this JavaType and, if so, use it.
// this mimics the legacy handling
@ -314,7 +304,6 @@ public class InferredBasicValueResolver {
jdbcMapping.getJavaTypeDescriptor(),
jdbcMapping.getJavaTypeDescriptor(),
jdbcMapping.getJdbcType(),
null,
legacyType,
null
);
@ -435,21 +424,20 @@ public class InferredBasicValueResolver {
jdbcType,
relationalJtd
);
final CustomType<E> customType = new CustomType<>(
new org.hibernate.type.EnumType<>(
enumJavaType.getJavaTypeClass(),
valueConverter,
typeConfiguration
),
typeConfiguration
);
return new InferredBasicValueResolution<>(
typeConfiguration.getBasicTypeRegistry().resolve( relationalJtd, jdbcType ),
customType,
enumJavaType,
relationalJtd,
jdbcType,
valueConverter,
new CustomType<>(
new org.hibernate.type.EnumType<>(
enumJavaType.getJavaTypeClass(),
valueConverter,
typeConfiguration
),
typeConfiguration
),
customType,
ImmutableMutabilityPlan.instance()
);
}
@ -487,21 +475,20 @@ public class InferredBasicValueResolver {
jdbcType,
relationalJtd
);
final CustomType<E> customType = new CustomType<>(
new org.hibernate.type.EnumType<>(
enumJavaType.getJavaTypeClass(),
valueConverter,
typeConfiguration
),
typeConfiguration
);
return new InferredBasicValueResolution<>(
typeConfiguration.getBasicTypeRegistry().resolve(relationalJtd, jdbcType),
customType,
enumJavaType,
relationalJtd,
jdbcType,
valueConverter,
new CustomType<>(
new org.hibernate.type.EnumType<>(
enumJavaType.getJavaTypeClass(),
valueConverter,
typeConfiguration
),
typeConfiguration
),
customType,
ImmutableMutabilityPlan.instance()
);
}
@ -548,7 +535,6 @@ public class InferredBasicValueResolver {
explicitTemporalJtd,
explicitTemporalJtd,
jdbcType,
null,
jdbcMapping,
explicitTemporalJtd.getMutabilityPlan()
);
@ -580,7 +566,6 @@ public class InferredBasicValueResolver {
jtd,
jtd,
explicitJdbcType,
null,
jdbcMapping,
jtd.getMutabilityPlan()
);
@ -610,7 +595,6 @@ public class InferredBasicValueResolver {
basicType.getJavaTypeDescriptor(),
basicType.getJavaTypeDescriptor(),
basicType.getJdbcType(),
null,
basicType,
reflectedJtd.getMutabilityPlan()
);

View File

@ -7,12 +7,10 @@
package org.hibernate.boot.model.process.internal;
import java.util.function.Function;
import jakarta.persistence.AttributeConverter;
import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor;
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
import org.hibernate.boot.model.convert.spi.JpaAttributeConverterCreationContext;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.mapping.BasicValue;
@ -20,13 +18,13 @@ import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.converter.AttributeConverterMutabilityPlanImpl;
import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
import org.hibernate.type.descriptor.java.BasicJavaType;
import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.internal.CustomMutabilityConvertedBasicTypeImpl;
import org.hibernate.type.spi.TypeConfiguration;
/**
@ -174,45 +172,7 @@ public class NamedConverterResolution<J> implements BasicValue.Resolution<J> {
assert mutabilityPlan != null;
this.mutabilityPlan = mutabilityPlan;
this.jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(
relationalJtd,
jdbcType
);
// this.jdbcMapping = new JdbcMapping() {
// private final ValueExtractor extractor = relationalStd.getExtractor( relationalJtd );
// private final ValueBinder binder = relationalStd.getBinder( relationalJtd );
//
// @Override
// public JavaType getJavaType() {
// return relationalJtd;
// }
//
// @Override
// public JdbcType getJdbcType() {
// return relationalStd;
// }
//
// @Override
// public ValueExtractor getJdbcValueExtractor() {
// return extractor;
// }
//
// @Override
// public ValueBinder getJdbcValueBinder() {
// return binder;
// }
// };
// this.jdbcMapping = new ConverterJdbcMappingImpl(
// domainJtd,
// relationalJtd,
// relationalStd,
// valueConverter,
// mutabilityPlan,
// typeConfiguration
// );
this.legacyResolvedType = new AttributeConverterTypeAdapter<>(
this.legacyResolvedType = new CustomMutabilityConvertedBasicTypeImpl<>(
ConverterDescriptor.TYPE_NAME_PREFIX
+ valueConverter.getConverterJavaType().getJavaType().getTypeName(),
String.format(
@ -220,12 +180,11 @@ public class NamedConverterResolution<J> implements BasicValue.Resolution<J> {
domainJtd.getJavaType().getTypeName(),
relationalJtd.getJavaType().getTypeName()
),
valueConverter,
jdbcType,
relationalJtd,
domainJtd,
valueConverter,
mutabilityPlan
);
this.jdbcMapping = legacyResolvedType;
}
@Override

View File

@ -65,6 +65,11 @@ public class ValueConverterTypeAdapter<J> extends AbstractSingleColumnStandardBa
valueBinder.bind( st, converted, index, options );
}
@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
return converter.toRelationalValue( (J) value );
}
@Override
protected MutabilityPlan<J> getMutabilityPlan() {
return converter.getDomainJavaType().getMutabilityPlan();
@ -81,6 +86,11 @@ public class ValueConverterTypeAdapter<J> extends AbstractSingleColumnStandardBa
return converter;
}
@Override
public JavaType<?> getJdbcJavaType() {
return converter.getRelationalJavaType();
}
@Override
public String toString() {
return description;

View File

@ -11,6 +11,7 @@ import java.lang.annotation.Repeatable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
@ -102,6 +103,7 @@ import org.hibernate.annotations.common.reflection.XPackage;
import org.hibernate.annotations.common.reflection.XProperty;
import org.hibernate.boot.model.IdGeneratorStrategyInterpreter;
import org.hibernate.boot.model.IdentifierGeneratorDefinition;
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
import org.hibernate.boot.model.convert.spi.RegisteredConversion;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
@ -117,7 +119,6 @@ import org.hibernate.cfg.annotations.Nullability;
import org.hibernate.cfg.annotations.PropertyBinder;
import org.hibernate.cfg.annotations.QueryBinder;
import org.hibernate.cfg.annotations.TableBinder;
import org.hibernate.cfg.internal.ConvertedJdbcMapping;
import org.hibernate.cfg.internal.NullableDiscriminatorColumnSecondPass;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.OptimisticLockStyle;
@ -125,6 +126,7 @@ import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.factory.spi.CustomIdGeneratorCreationContext;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.GenericsHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.jpa.event.internal.CallbackDefinitionResolverLegacyImpl;
import org.hibernate.jpa.event.spi.CallbackType;
@ -147,6 +149,7 @@ import org.hibernate.mapping.Subclass;
import org.hibernate.mapping.ToOne;
import org.hibernate.mapping.UnionSubclass;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.model.convert.internal.JpaAttributeConverterImpl;
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
import org.hibernate.property.access.internal.PropertyAccessStrategyCompositeUserTypeImpl;
import org.hibernate.property.access.internal.PropertyAccessStrategyMixedImpl;
@ -159,6 +162,7 @@ import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.CompositeUserType;
import org.hibernate.usertype.UserType;
@ -1756,7 +1760,35 @@ public final class AnnotationBinder {
final ManagedBeanRegistry beanRegistry = serviceRegistry.getService( ManagedBeanRegistry.class );
final ManagedBean<AttributeConverter<?, ?>> bean = beanRegistry.getBean( type );
return new ConvertedJdbcMapping<>( bean, context.getBootstrapContext().getTypeConfiguration() );
final TypeConfiguration typeConfiguration = context.getBootstrapContext().getTypeConfiguration();
final JavaTypeRegistry jtdRegistry = typeConfiguration.getJavaTypeRegistry();
final JavaType<? extends AttributeConverter<?,?>> converterJtd = jtdRegistry.resolveDescriptor( bean.getBeanClass() );
final ParameterizedType converterParameterizedType = GenericsHelper.extractParameterizedType( bean.getBeanClass() );
final Class<?> domainJavaClass = GenericsHelper.extractClass( converterParameterizedType.getActualTypeArguments()[0] );
final Class<?> relationalJavaClass = GenericsHelper.extractClass( converterParameterizedType.getActualTypeArguments()[1] );
final JavaType<?> domainJtd = jtdRegistry.resolveDescriptor( domainJavaClass );
final JavaType<?> relationalJtd = jtdRegistry.resolveDescriptor( relationalJavaClass );
@SuppressWarnings({ "unchecked", "rawtypes" })
final JpaAttributeConverterImpl valueConverter = new JpaAttributeConverterImpl(
bean,
converterJtd,
domainJtd,
relationalJtd
);
return new ConvertedBasicTypeImpl<>(
ConverterDescriptor.TYPE_NAME_PREFIX
+ valueConverter.getConverterJavaType().getJavaType().getTypeName(),
String.format(
"BasicType adapter for AttributeConverter<%s,%s>",
domainJtd.getJavaType().getTypeName(),
relationalJtd.getJavaType().getTypeName()
),
relationalJtd.getRecommendedJdbcType( typeConfiguration.getCurrentBaseSqlTypeIndicators() ),
valueConverter
);
}
private static JdbcMapping resolveJavaType(Class<JavaType<?>> type, MetadataBuildingContext context) {

View File

@ -8,13 +8,13 @@ package org.hibernate.cfg.internal;
import java.lang.reflect.ParameterizedType;
import org.hibernate.Remove;
import org.hibernate.internal.util.GenericsHelper;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.model.convert.internal.JpaAttributeConverterImpl;
import org.hibernate.resource.beans.spi.ManagedBean;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.converter.AttributeConverterJdbcTypeAdapter;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.descriptor.jdbc.JdbcType;
@ -26,7 +26,10 @@ import jakarta.persistence.AttributeConverter;
* Ad-hoc JdbcMapping implementation for cases where we only have a converter
*
* @author Steve Ebersole
* @deprecated remove
*/
@Remove
@Deprecated(forRemoval = true)
public class ConvertedJdbcMapping<T> implements JdbcMapping {
private final JavaType<T> domainJtd;
@ -55,11 +58,12 @@ public class ConvertedJdbcMapping<T> implements JdbcMapping {
relationalJtd
);
this.jdbcType = new AttributeConverterJdbcTypeAdapter(
converterDescriptor,
relationalJtd.getRecommendedJdbcType( typeConfiguration.getCurrentBaseSqlTypeIndicators() ),
relationalJtd
);
this.jdbcType = null;
// new AttributeConverterJdbcTypeAdapter(
// converterDescriptor,
// relationalJtd.getRecommendedJdbcType( typeConfiguration.getCurrentBaseSqlTypeIndicators() ),
// relationalJtd
// );
}
@Override
@ -72,6 +76,11 @@ public class ConvertedJdbcMapping<T> implements JdbcMapping {
return jdbcType;
}
@Override
public JavaType<?> getJdbcJavaType() {
return relationalJtd;
}
@Override
public ValueExtractor<?> getJdbcValueExtractor() {
return jdbcType.getExtractor( domainJtd );

View File

@ -9,11 +9,13 @@ package org.hibernate.internal;
import java.util.Objects;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
import org.hibernate.sql.exec.spi.JdbcParameterBinder;
import org.hibernate.sql.exec.spi.JdbcParameterBinding;
import org.hibernate.type.descriptor.java.JavaType;
/**
* @author Nathan Xu
@ -38,7 +40,11 @@ public class FilterJdbcParameter {
}
public JdbcParameterBinding getBinding() {
return new JdbcParameterBindingImpl( jdbcMapping, jdbcParameterValue );
final BasicValueConverter valueConverter = jdbcMapping.getValueConverter();
if ( valueConverter == null ) {
return new JdbcParameterBindingImpl( jdbcMapping, jdbcParameterValue );
}
return new JdbcParameterBindingImpl( jdbcMapping, valueConverter.toRelationalValue( jdbcParameterValue ) );
}
@Override
@ -52,11 +58,18 @@ public class FilterJdbcParameter {
FilterJdbcParameter that = (FilterJdbcParameter) o;
return Objects.equals( parameter, that.parameter ) &&
Objects.equals( jdbcMapping, that.jdbcMapping ) &&
Objects.equals( jdbcParameterValue, that.jdbcParameterValue );
( (JavaType<Object>) jdbcMapping.getMappedJavaType() ).areEqual(
jdbcParameterValue,
that.jdbcParameterValue
);
}
@Override
public int hashCode() {
return Objects.hash( parameter, jdbcMapping, jdbcParameterValue );
return Objects.hash(
parameter,
jdbcMapping,
( (JavaType<Object>) jdbcMapping.getMappedJavaType() ).extractHashCode( jdbcParameterValue )
);
}
}

View File

@ -20,7 +20,7 @@ import org.hibernate.boot.model.TypeDefinitionRegistry;
import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor;
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
import org.hibernate.boot.model.convert.spi.JpaAttributeConverterCreationContext;
import org.hibernate.boot.model.process.internal.ConvertedBasicTypeResolution;
import org.hibernate.boot.model.process.internal.InferredBasicValueResolution;
import org.hibernate.boot.model.process.internal.InferredBasicValueResolver;
import org.hibernate.boot.model.process.internal.NamedBasicTypeResolution;
import org.hibernate.boot.model.process.internal.NamedConverterResolution;
@ -44,11 +44,12 @@ import org.hibernate.resource.beans.spi.BeanInstanceProducer;
import org.hibernate.resource.beans.spi.ManagedBean;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
import org.hibernate.type.BasicType;
import org.hibernate.type.ConvertedBasicType;
import org.hibernate.type.CustomType;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.BasicJavaType;
import org.hibernate.type.descriptor.java.BasicPluralJavaType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.jdbc.JdbcType;
@ -377,36 +378,6 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
);
}
final ConverterDescriptor attributeConverterDescriptor = getAttributeConverterDescriptor();
if ( attributeConverterDescriptor != null ) {
final ManagedBeanRegistry managedBeanRegistry = getBuildingContext().getBootstrapContext()
.getServiceRegistry()
.getService( ManagedBeanRegistry.class );
final JpaAttributeConverterCreationContext converterCreationContext = new JpaAttributeConverterCreationContext() {
@Override
public ManagedBeanRegistry getManagedBeanRegistry() {
return managedBeanRegistry;
}
@Override
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
};
return NamedConverterResolution.from(
attributeConverterDescriptor,
explicitJavaTypeAccess,
explicitJdbcTypeAccess,
explicitMutabilityPlanAccess,
this,
converterCreationContext,
getBuildingContext()
);
}
JavaType<?> jtd = null;
// determine JavaType if we can
@ -438,6 +409,71 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
}
}
final ConverterDescriptor attributeConverterDescriptor = getAttributeConverterDescriptor();
if ( attributeConverterDescriptor != null ) {
final ManagedBeanRegistry managedBeanRegistry = getBuildingContext().getBootstrapContext()
.getServiceRegistry()
.getService( ManagedBeanRegistry.class );
final JpaAttributeConverterCreationContext converterCreationContext = new JpaAttributeConverterCreationContext() {
@Override
public ManagedBeanRegistry getManagedBeanRegistry() {
return managedBeanRegistry;
}
@Override
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
};
final NamedConverterResolution<Object> converterResolution = NamedConverterResolution.from(
attributeConverterDescriptor,
explicitJavaTypeAccess,
explicitJdbcTypeAccess,
explicitMutabilityPlanAccess,
this,
converterCreationContext,
getBuildingContext()
);
if ( jtd instanceof BasicPluralJavaType<?>
&& !attributeConverterDescriptor.getDomainValueResolvedType()
.getErasedType()
.isAssignableFrom( jtd.getJavaTypeClass() ) ) {
// In this case, the converter applies to the element of a BasicPluralJavaType
final BasicPluralJavaType<?> containerJtd = (BasicPluralJavaType<?>) jtd;
final BasicType registeredElementType = converterResolution.getLegacyResolvedBasicType();
final ColumnTypeInformation columnTypeInformation;
if ( getColumn() instanceof ColumnTypeInformation ) {
columnTypeInformation = (ColumnTypeInformation) getColumn();
}
else {
columnTypeInformation = null;
}
final BasicType<?> registeredType = registeredElementType == null ? null : containerJtd.resolveType(
typeConfiguration,
getMetadata().getDatabase().getDialect(),
registeredElementType,
columnTypeInformation
);
if ( registeredType != null ) {
typeConfiguration.getBasicTypeRegistry().register( registeredType );
return new InferredBasicValueResolution(
registeredType,
registeredType.getJavaTypeDescriptor(),
registeredType.getJavaTypeDescriptor(),
registeredType.getJdbcType(),
registeredType,
null
);
}
}
return converterResolution;
}
final JdbcType jdbcType;
if ( explicitJdbcTypeAccess != null ) {
jdbcType = explicitJdbcTypeAccess.apply( typeConfiguration );
@ -587,16 +623,8 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
valueConverter = converterDescriptor.createJpaAttributeConverter( converterCreationContext );
domainJtd = valueConverter.getDomainJavaType();
}
else if ( basicTypeByName instanceof ConvertedBasicType ) {
final ConvertedBasicType<?> convertedType = (ConvertedBasicType<?>) basicTypeByName;
if ( convertedType.getValueConverter() != null ) {
return new ConvertedBasicTypeResolution<>( convertedType, stdIndicators );
}
valueConverter = null;
domainJtd = basicTypeByName.getJavaTypeDescriptor();
}
else {
valueConverter = null;
valueConverter = basicTypeByName.getValueConverter();
domainJtd = basicTypeByName.getJavaTypeDescriptor();
}

View File

@ -27,7 +27,9 @@ import org.hibernate.type.BasicType;
import org.hibernate.type.ComponentType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.ArrayJdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.spi.TypeConfiguration;
import static org.hibernate.internal.util.StringHelper.safeInterning;
@ -345,9 +347,12 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
if ( type instanceof ComponentType ) {
type = getTypeForComponentValue( mapping, type, getTypeIndex() );
}
final JdbcMapping jdbcMapping = (JdbcMapping) type;
final JdbcType jdbcType = jdbcMapping.getJdbcType();
final JavaType<?> javaType = jdbcMapping.getJdbcJavaType();
columnSize = dialect.getSizeStrategy().resolveSize(
( (JdbcMapping) type ).getJdbcType(),
( (JdbcMapping) type ).getJavaTypeDescriptor(),
jdbcType,
javaType,
precision,
scale,
length

View File

@ -54,13 +54,12 @@ import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.JdbcTypeNameMapper;
import org.hibernate.type.descriptor.converter.AttributeConverterJdbcTypeAdapter;
import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.descriptor.jdbc.LobTypeMappings;
import org.hibernate.type.descriptor.jdbc.NationalizedTypeMappings;
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.DynamicParameterizedType;
@ -799,7 +798,7 @@ public abstract class SimpleValue implements KeyValue {
) );
}
private <T> AttributeConverterTypeAdapter<T> buildAttributeConverterTypeAdapter(
private <T> Type buildAttributeConverterTypeAdapter(
JpaAttributeConverter<T, ?> jpaAttributeConverter) {
JavaType<T> domainJavaType = jpaAttributeConverter.getDomainJavaType();
JavaType<?> relationalJavaType = jpaAttributeConverter.getRelationalJavaType();
@ -851,7 +850,7 @@ public abstract class SimpleValue implements KeyValue {
// todo : cache the AttributeConverterTypeAdapter in case that AttributeConverter is applied multiple times.
return new AttributeConverterTypeAdapter<>(
return new ConvertedBasicTypeImpl<>(
ConverterDescriptor.TYPE_NAME_PREFIX
+ jpaAttributeConverter.getConverterJavaType().getJavaType().getTypeName(),
String.format(
@ -859,17 +858,8 @@ public abstract class SimpleValue implements KeyValue {
domainJavaType.getJavaType().getTypeName(),
relationalJavaType.getJavaType().getTypeName()
),
jpaAttributeConverter,
// and finally construct the adapter, which injects the AttributeConverter
// calls into the binding/extraction process...
new AttributeConverterJdbcTypeAdapter(
jpaAttributeConverter,
metadata.getTypeConfiguration().getJdbcTypeRegistry().getDescriptor( jdbcTypeCode ),
relationalJavaType
),
relationalJavaType,
domainJavaType,
null
metadata.getTypeConfiguration().getJdbcTypeRegistry().getDescriptor( jdbcTypeCode ),
jpaAttributeConverter
);
}

View File

@ -17,5 +17,7 @@ public interface ConvertibleModelPart extends BasicValuedModelPart {
/**
* Get the value converter applied to this model part if any
*/
BasicValueConverter getValueConverter();
default BasicValueConverter getValueConverter() {
return getJdbcMapping().getValueConverter();
}
}

View File

@ -9,11 +9,14 @@ package org.hibernate.metamodel.mapping;
import java.util.Collections;
import java.util.List;
import org.hibernate.Incubating;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.query.sqm.CastType;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.hibernate.type.descriptor.jdbc.JdbcType;
/**
@ -50,11 +53,34 @@ public interface JdbcMapping extends MappingType, JdbcMappingContainer {
*/
ValueBinder getJdbcValueBinder();
/**
* The strategy for formatting values of this expressible type to
* a SQL literal.
*/
@Incubating
default JdbcLiteralFormatter getJdbcLiteralFormatter() {
return getJdbcType().getJdbcLiteralFormatter( getMappedJavaType() );
}
@Override
default JavaType<?> getMappedJavaType() {
return getJavaTypeDescriptor();
}
@Incubating
default JavaType<?> getJdbcJavaType() {
return getJavaTypeDescriptor();
}
/**
* Returns the converter that this basic type uses for transforming from the domain type, to the relational type,
* or <code>null</code> if there is no conversion.
*/
@Incubating
default BasicValueConverter getValueConverter() {
return null;
}
@Override
default int getJdbcTypeCount() {
return 1;

View File

@ -7,9 +7,7 @@
package org.hibernate.metamodel.mapping.internal;
import java.util.function.BiConsumer;
import java.util.function.Function;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
@ -19,7 +17,6 @@ import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.metamodel.mapping.SelectableConsumer;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.persister.entity.DiscriminatorType;
import org.hibernate.persister.entity.EntityPersister;
@ -36,10 +33,6 @@ import org.hibernate.sql.results.graph.basic.BasicFetch;
import org.hibernate.sql.results.graph.basic.BasicResult;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
import static org.hibernate.metamodel.RepresentationMode.MAP;
/**
* @implNote `discriminatorType` represents the mapping to Class, whereas `discriminatorType.getUnderlyingType()`
@ -49,33 +42,20 @@ import static org.hibernate.metamodel.RepresentationMode.MAP;
*/
public abstract class AbstractDiscriminatorMapping implements EntityDiscriminatorMapping {
private final NavigableRole role;
private final JdbcMapping jdbcMapping;
private final EntityPersister entityDescriptor;
private final DiscriminatorType<?> discriminatorType;
private final SessionFactoryImplementor sessionFactory;
private final DomainResultConverter<?> domainResultConverter;
public AbstractDiscriminatorMapping(
JdbcMapping jdbcMapping,
EntityPersister entityDescriptor,
DiscriminatorType<?> discriminatorType,
MappingModelCreationProcess creationProcess) {
this.jdbcMapping = jdbcMapping;
this.entityDescriptor = entityDescriptor;
this.discriminatorType = discriminatorType;
role = entityDescriptor.getNavigableRole().append( EntityDiscriminatorMapping.ROLE_NAME );
sessionFactory = creationProcess.getCreationContext().getSessionFactory();
domainResultConverter = DomainResultConverter.create(
entityDescriptor,
this::getConcreteEntityNameForDiscriminatorValue,
discriminatorType.getUnderlyingType(),
sessionFactory
);
}
public EntityPersister getEntityDescriptor() {
@ -101,7 +81,7 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
@Override
public JdbcMapping getJdbcMapping() {
return jdbcMapping;
return discriminatorType;
}
@Override
@ -138,12 +118,10 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
creationState.getSqlAstCreationState()
);
//noinspection unchecked
return new BasicResult(
return new BasicResult<>(
sqlSelection.getValuesArrayPosition(),
resultVariable,
domainResultConverter.getDomainJavaType(),
domainResultConverter,
discriminatorType,
navigablePath
);
}
@ -157,7 +135,7 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
final SqlExpressionResolver expressionResolver = creationState.getSqlExpressionResolver();
return expressionResolver.resolveSqlSelection(
resolveSqlExpression( navigablePath, jdbcMappingToUse, tableGroup, creationState ),
jdbcMappingToUse.getJavaTypeDescriptor(),
jdbcMappingToUse.getJdbcJavaType(),
fetchParent,
creationState.getCreationContext().getSessionFactory().getTypeConfiguration()
);
@ -191,7 +169,6 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
fetchParent,
fetchablePath,
this,
null,
fetchTiming,
creationState
);
@ -224,7 +201,7 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
valuesConsumer.consume( offset, convertToRelational( value ), getJdbcMapping() );
valuesConsumer.consume( offset, value, getJdbcMapping() );
return getJdbcTypeCount();
}
@ -236,175 +213,18 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
@Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) {
valueConsumer.consume( convertToRelational( domainValue ), this );
}
private Object convertToRelational(Object domainValue) {
if ( domainResultConverter != null ) {
return domainResultConverter.toRelationalValue( domainValue );
}
return domainValue;
valueConsumer.consume( disassemble( domainValue, session ), this );
}
@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
return convertToRelational( value );
}
@Override
public int forEachJdbcValue(Object value, Clause clause, int offset, JdbcValuesConsumer valuesConsumer, SharedSessionContractImplementor session) {
valuesConsumer.consume( offset, convertToRelational( value ), jdbcMapping );
return 1;
}
@Override
public int forEachSelectable(SelectableConsumer consumer) {
return EntityDiscriminatorMapping.super.forEachSelectable( consumer );
return value;
}
@Override
public int forEachSelectable(int offset, SelectableConsumer consumer) {
return EntityDiscriminatorMapping.super.forEachSelectable( offset, consumer );
}
@Override
public int forEachJdbcType(IndexedConsumer<JdbcMapping> action) {
return EntityDiscriminatorMapping.super.forEachJdbcType( action );
}
/**
* Used to convert the underlying discriminator value into a Class (or String for entity-name)
* reference for the entity type
*/
protected static class DomainResultConverter<R> implements BasicValueConverter<Object,R> {
/**
* Given a "raw" discriminator value, determines the corresponding concrete entity name
*/
private final Function<R,String> subtypeResolver;
/**
* Given a concrete entity name, apply the conversion to determine the "domain result" value
*
* @apiNote This is only used when building a {@link DomainResult}
*/
private final Function<String, Object> entityNameHandler;
/**
* Given a "domain form", apply the conversion to determine the corresponding relational value
*/
private final Function<Object, R> toRelationalConverter;
private final JavaType<Object> domainJtd;
private final JavaType<R> relationalJtd;
public DomainResultConverter(
Function<R,String> subtypeResolver,
Function<String,Object> entityNameHandler,
Function<Object,R> toRelationalConverter,
JavaType<Object> domainJtd,
JavaType<R> relationalJtd) {
this.subtypeResolver = subtypeResolver;
this.entityNameHandler = entityNameHandler;
this.toRelationalConverter = toRelationalConverter;
this.domainJtd = domainJtd;
this.relationalJtd = relationalJtd;
}
private static <R> DomainResultConverter<R> create(
EntityPersister entityDescriptor,
Function<R,String> subtypeResolver,
BasicType underlyingDiscriminatorType,
final SessionFactoryImplementor sessionFactory) {
final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration();
final JavaTypeRegistry jtdRegistry = typeConfiguration.getJavaTypeRegistry();
final JavaType<Object> domainJtd;
final Function<String,Object> entityNameHandler;
final Function<Object,Object> toRelationalConverter;
if ( entityDescriptor.getRepresentationStrategy().getMode() == MAP ) {
// todo (6.0) : account for explicit entity-name which should also return String
domainJtd = jtdRegistry.getDescriptor( String.class );
entityNameHandler = (entityName) -> entityName;
toRelationalConverter = (domainValue) -> {
if ( domainValue instanceof Class ) {
throw new IllegalArgumentException( "Illegal attempt to specify Class for discriminator for dynamic entity" );
}
if ( domainValue instanceof String ) {
final String stringValue = (String) domainValue;
// could be either an entity name or "underlying type" (e.g. mapped to VARCHAR)
// - first we check as an entity name since that's a discrete set;
// - handling as an "underlying type" value is handled in "otherwise"
if ( entityDescriptor.isSubclassEntityName( stringValue ) ) {
return entityDescriptor.getDiscriminatorValue();
}
}
// otherwise we assume its an instance of the underlying type
assert underlyingDiscriminatorType.getJavaTypeDescriptor().getJavaTypeClass().isInstance( domainJtd );
return domainJtd;
};
}
else {
final ClassLoaderService cls = sessionFactory.getServiceRegistry().getService( ClassLoaderService.class );
domainJtd = jtdRegistry.getDescriptor( Class.class );
entityNameHandler = cls::classForName;
toRelationalConverter = (domainValue) -> {
if ( domainValue instanceof Class ) {
final Class<?> classValue = (Class<?>) domainValue;
final EntityMappingType concreteEntityMapping = sessionFactory.getRuntimeMetamodels().getEntityMappingType( classValue );
return concreteEntityMapping.getDiscriminatorValue();
}
if ( domainValue instanceof String ) {
final String stringValue = (String) domainValue;
// could be either an entity name or "underlying type" (e.g. mapped to VARCHAR)
// - first we check as an entity name since that's a discrete set;
// - handling as an "underlying type" value is handled in "otherwise"
if ( entityDescriptor.isSubclassEntityName( stringValue ) ) {
return entityDescriptor.getDiscriminatorValue();
}
}
// otherwise we assume its an instance of the underlying type
assert underlyingDiscriminatorType.getJavaTypeDescriptor().getJavaTypeClass().isInstance( domainJtd );
return domainJtd;
};
}
return new DomainResultConverter(
subtypeResolver,
entityNameHandler,
toRelationalConverter,
domainJtd,
underlyingDiscriminatorType.getJavaTypeDescriptor()
);
}
@Override
public Object toDomainValue(R relationalForm) {
final String entityName = subtypeResolver.apply( relationalForm );
return entityNameHandler.apply( entityName );
}
@Override
public R toRelationalValue(Object domainForm) {
// the domainForm could be any of Class (entity type), String (entity-name) or
// underlying type (String, Integer, ..)
return toRelationalConverter.apply( domainForm );
}
@Override
public JavaType<Object> getDomainJavaType() {
return domainJtd;
}
@Override
public JavaType<R> getRelationalJavaType() {
return relationalJtd;
}
consumer.accept( offset, this );
return getJdbcTypeCount();
}
}

View File

@ -273,7 +273,7 @@ public class AnyDiscriminatorPart implements BasicValuedModelPart, FetchOptions,
);
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
columnReference,
jdbcMapping().getMappedJavaType(),
jdbcMapping().getJdbcJavaType(),
fetchParent,
sessionFactory.getTypeConfiguration()
);
@ -283,7 +283,6 @@ public class AnyDiscriminatorPart implements BasicValuedModelPart, FetchOptions,
fetchParent,
fetchablePath,
this,
null,
fetchTiming,
creationState
);

View File

@ -198,7 +198,7 @@ public class AnyKeyPart implements BasicValuedModelPart, FetchOptions {
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
columnReference,
getJavaType(),
jdbcMapping.getJdbcJavaType(),
fetchParent,
sessionFactory.getTypeConfiguration()
);
@ -208,7 +208,6 @@ public class AnyKeyPart implements BasicValuedModelPart, FetchOptions {
fetchParent,
fetchablePath,
this,
null,
fetchTiming,
creationState
);

View File

@ -40,6 +40,7 @@ import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.basic.BasicFetch;
import org.hibernate.sql.results.graph.basic.BasicResult;
import org.hibernate.tuple.ValueGeneration;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.JavaType;
/**
@ -62,7 +63,6 @@ public class BasicAttributeMapping
private final Integer scale;
private final JdbcMapping jdbcMapping;
private final BasicValueConverter<Object, ?> valueConverter;
private final JavaType domainTypeDescriptor;
@ -82,7 +82,6 @@ public class BasicAttributeMapping
Long length,
Integer precision,
Integer scale,
BasicValueConverter valueConverter,
JdbcMapping jdbcMapping,
ManagedMappingType declaringType,
PropertyAccess propertyAccess,
@ -105,15 +104,8 @@ public class BasicAttributeMapping
this.length = length;
this.precision = precision;
this.scale = scale;
this.valueConverter = valueConverter;
this.jdbcMapping = jdbcMapping;
if ( valueConverter == null ) {
domainTypeDescriptor = jdbcMapping.getJavaTypeDescriptor();
}
else {
domainTypeDescriptor = valueConverter.getDomainJavaType();
}
this.domainTypeDescriptor = jdbcMapping.getJavaTypeDescriptor();
this.customReadExpression = customReadExpression;
@ -134,7 +126,6 @@ public class BasicAttributeMapping
String attributeName = null;
int stateArrayPosition = 0;
AttributeMetadataAccess attributeMetadataAccess = null;
BasicValueConverter<?, ?> valueConverter = null;
if ( original instanceof SingleAttributeIdentifierMapping ) {
final SingleAttributeIdentifierMapping mapping = (SingleAttributeIdentifierMapping) original;
attributeName = mapping.getAttributeName();
@ -146,9 +137,6 @@ public class BasicAttributeMapping
stateArrayPosition = mapping.getStateArrayPosition();
attributeMetadataAccess = mapping.getAttributeMetadataAccess();
}
if ( original instanceof ConvertibleModelPart ) {
valueConverter = ( (ConvertibleModelPart) original ).getValueConverter();
}
return new BasicAttributeMapping(
attributeName,
original.getNavigableRole(),
@ -165,7 +153,6 @@ public class BasicAttributeMapping
selectableMapping.getLength(),
selectableMapping.getPrecision(),
selectableMapping.getScale(),
valueConverter,
original.getJdbcMapping(),
declaringType,
propertyAccess,
@ -233,11 +220,6 @@ public class BasicAttributeMapping
return tableExpression;
}
@Override
public BasicValueConverter getValueConverter() {
return valueConverter;
}
@Override
public NavigableRole getNavigableRole() {
return navigableRole;
@ -260,8 +242,7 @@ public class BasicAttributeMapping
return new BasicResult(
sqlSelection.getValuesArrayPosition(),
resultVariable,
getMappedType().getMappedJavaType(),
valueConverter,
jdbcMapping,
navigablePath
);
}
@ -291,7 +272,7 @@ public class BasicAttributeMapping
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
)
),
valueConverter == null ? getMappedType().getMappedJavaType() : valueConverter.getRelationalJavaType(),
jdbcMapping.getJdbcJavaType(),
fetchParent,
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory().getTypeConfiguration()
);
@ -347,7 +328,6 @@ public class BasicAttributeMapping
fetchParent,
fetchablePath,
this,
valueConverter,
fetchTiming,
creationState
);
@ -355,8 +335,9 @@ public class BasicAttributeMapping
@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
if ( valueConverter != null ) {
return valueConverter.toRelationalValue( value );
if ( jdbcMapping.getValueConverter() != null ) {
//noinspection unchecked
return jdbcMapping.getValueConverter().toRelationalValue( value );
}
return value;
}

View File

@ -68,7 +68,7 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
private final Integer precision;
private final Integer scale;
private final BasicType<?> idType;
private final BasicType<Object> idType;
private final SessionFactoryImplementor sessionFactory;
@ -92,7 +92,7 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
this.attributeName = attributeName;
this.rootTable = rootTable;
this.pkColumnName = pkColumnName;
this.idType = idType;
this.idType = (BasicType<Object>) idType;
this.entityPersister = entityPersister;
final PersistentClass bootEntityDescriptor = creationProcess.getCreationContext()
@ -188,17 +188,6 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
return getJdbcTypeCount();
}
@Override
public int forEachJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
valuesConsumer.consume( offset, value, idType );
return getJdbcTypeCount();
}
@Override
public JavaType<?> getJavaType() {
return getMappedType().getMappedJavaType();
@ -217,10 +206,10 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
DomainResultCreationState creationState) {
final SqlSelection sqlSelection = resolveSqlSelection( navigablePath, tableGroup, true, null, creationState );
return new BasicResult(
return new BasicResult<>(
sqlSelection.getValuesArrayPosition(),
resultVariable,
entityPersister.getIdentifierMapping().getMappedType().getMappedJavaType(),
entityPersister.getIdentifierMapping().getJdbcMappings().get( 0 ),
navigablePath
);
}
@ -285,7 +274,7 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
return expressionResolver.resolveSqlSelection(
expression,
idType.getExpressibleJavaType(),
idType.getJdbcJavaType(),
fetchParent,
sessionFactory.getTypeConfiguration()
);
@ -353,11 +342,7 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
if ( value == null ) {
return null;
}
return value;
// return propertyAccess.getGetter().get( value );
return idType.disassemble( value, session );
}
@Override
@ -391,7 +376,6 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
fetchParent,
fetchablePath,
this,
null,
FetchTiming.IMMEDIATE,
creationState
);

View File

@ -54,19 +54,16 @@ public class BasicValuedCollectionPart
private final NavigableRole navigableRole;
private final CollectionPersister collectionDescriptor;
private final Nature nature;
private final BasicValueConverter<Object, ?> valueConverter;
private final SelectableMapping selectableMapping;
public BasicValuedCollectionPart(
CollectionPersister collectionDescriptor,
Nature nature,
BasicValueConverter valueConverter,
SelectableMapping selectableMapping) {
this.navigableRole = collectionDescriptor.getNavigableRole().append( nature.getName() );
this.collectionDescriptor = collectionDescriptor;
this.nature = nature;
this.valueConverter = valueConverter;
this.selectableMapping = selectableMapping;
}
@ -125,11 +122,6 @@ public class BasicValuedCollectionPart
return selectableMapping.getScale();
}
@Override
public BasicValueConverter getValueConverter() {
return valueConverter;
}
@Override
public JavaType<?> getJavaType() {
return selectableMapping.getJdbcMapping().getJavaTypeDescriptor();
@ -153,12 +145,10 @@ public class BasicValuedCollectionPart
DomainResultCreationState creationState) {
final SqlSelection sqlSelection = resolveSqlSelection( navigablePath, tableGroup, true, null, creationState );
//noinspection unchecked
return new BasicResult(
return new BasicResult<>(
sqlSelection.getValuesArrayPosition(),
resultVariable,
getJavaType(),
valueConverter,
selectableMapping.getJdbcMapping(),
navigablePath
);
}
@ -197,7 +187,7 @@ public class BasicValuedCollectionPart
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
)
),
getJavaType(),
getJdbcMapping().getJdbcJavaType(),
fetchParent,
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory().getTypeConfiguration()
);
@ -272,7 +262,6 @@ public class BasicValuedCollectionPart
fetchParent,
fetchablePath,
this,
valueConverter,
FetchTiming.IMMEDIATE,
creationState
);
@ -323,8 +312,8 @@ public class BasicValuedCollectionPart
@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
if ( valueConverter != null ) {
return valueConverter.toRelationalValue( value );
if ( selectableMapping.getJdbcMapping().getValueConverter() != null ) {
return selectableMapping.getJdbcMapping().getValueConverter().toRelationalValue( value );
}
return value;
}

View File

@ -51,12 +51,7 @@ public class CaseStatementDiscriminatorMappingImpl extends AbstractDiscriminator
Map<String,String> subEntityNameByTableName,
DiscriminatorType<?> incomingDiscriminatorType,
MappingModelCreationProcess creationProcess) {
super(
incomingDiscriminatorType.getUnderlyingType().getJdbcMapping(),
entityDescriptor,
incomingDiscriminatorType,
creationProcess
);
super( entityDescriptor, incomingDiscriminatorType, creationProcess );
for ( int i = 0; i < discriminatorValues.length; i++ ) {
final String tableName = tableNames[notNullColumnTableNumbers[i]];

View File

@ -230,7 +230,7 @@ public class CollectionIdentifierDescriptorImpl implements CollectionIdentifierD
sessionFactory
)
),
type.getJavaTypeDescriptor(),
type.getJdbcJavaType(),
fetchParent,
sessionFactory.getTypeConfiguration()
);
@ -240,7 +240,6 @@ public class CollectionIdentifierDescriptorImpl implements CollectionIdentifierD
fetchParent,
fetchablePath,
this,
null,
FetchTiming.IMMEDIATE,
creationState
);
@ -271,16 +270,15 @@ public class CollectionIdentifierDescriptorImpl implements CollectionIdentifierD
sessionFactory
)
),
type.getJavaTypeDescriptor(),
type.getJdbcJavaType(),
null,
sessionFactory.getTypeConfiguration()
);
//noinspection unchecked
return new BasicResult<>(
sqlSelection.getValuesArrayPosition(),
null,
(JavaType<Object>) type.getJavaTypeDescriptor(),
type,
collectionPath
);
}

View File

@ -105,15 +105,15 @@ public class EntityRowIdMappingImpl implements EntityRowIdMapping, SelectableMap
sqlAstCreationState.getCreationContext().getSessionFactory()
)
),
rowIdType.getJavaTypeDescriptor(),
rowIdType.getJdbcJavaType(),
null,
sqlAstCreationState.getCreationContext().getSessionFactory().getTypeConfiguration()
);
return new BasicResult(
return new BasicResult<>(
sqlSelection.getValuesArrayPosition(),
resultVariable,
rowIdType.getJavaTypeDescriptor(),
rowIdType,
navigablePath
);
}

View File

@ -226,7 +226,7 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti
sqlAstCreationState.getCreationContext().getSessionFactory()
)
),
versionBasicType.getJdbcMapping().getJavaTypeDescriptor(),
versionBasicType.getJdbcJavaType(),
fetchParent,
sqlAstCreationState.getCreationContext().getSessionFactory().getTypeConfiguration()
);
@ -236,7 +236,6 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti
fetchParent,
fetchablePath,
this,
null,
fetchTiming,
creationState
);
@ -250,10 +249,10 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti
DomainResultCreationState creationState) {
final SqlSelection sqlSelection = resolveSqlSelection( tableGroup, creationState );
return new BasicResult(
return new BasicResult<>(
sqlSelection.getValuesArrayPosition(),
resultVariable,
getJavaType(),
versionBasicType,
navigablePath
);
}
@ -301,7 +300,7 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti
sqlAstCreationState.getCreationContext().getSessionFactory()
)
),
versionBasicType.getJdbcMapping().getJavaTypeDescriptor(),
versionBasicType.getJdbcJavaType(),
null,
sqlAstCreationState.getCreationContext().getSessionFactory().getTypeConfiguration()
);

View File

@ -44,7 +44,7 @@ public class ExplicitColumnDiscriminatorMappingImpl extends AbstractDiscriminato
Integer precision,
Integer scale,
MappingModelCreationProcess creationProcess) {
super( discriminatorType.getJdbcMapping(), entityDescriptor, discriminatorType, creationProcess );
super( entityDescriptor, discriminatorType, creationProcess );
this.tableExpression = tableExpression;
this.isPhysical = isPhysical;
this.columnDefinition = columnDefinition;
@ -78,7 +78,7 @@ public class ExplicitColumnDiscriminatorMappingImpl extends AbstractDiscriminato
columnFormula != null,
null,
null,
jdbcMappingToUse,
getJdbcMapping(),
getSessionFactory()
)

View File

@ -17,6 +17,7 @@ import org.hibernate.MappingException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.SharedSessionContract;
import org.hibernate.annotations.NotFoundAction;
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
import org.hibernate.collection.internal.StandardArraySemantics;
import org.hibernate.collection.internal.StandardBagSemantics;
@ -73,6 +74,7 @@ import org.hibernate.metamodel.mapping.SelectableMapping;
import org.hibernate.metamodel.mapping.SelectableMappings;
import org.hibernate.metamodel.mapping.VirtualModelPart;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.collection.CollectionPersister;
@ -189,8 +191,6 @@ public class MappingModelCreationHelper {
final Value value = bootProperty.getValue();
final BasicValue.Resolution<?> resolution = ( (Resolvable) value ).resolve();
final BasicValueConverter<?,?> valueConverter = resolution.getValueConverter();
final AttributeMetadataAccess attributeMetadataAccess = entityMappingType -> new AttributeMetadata() {
private final MutabilityPlan mutabilityPlan = resolution.getMutabilityPlan();
private final boolean nullable = value.isNullable();
@ -259,71 +259,27 @@ public class MappingModelCreationHelper {
}
final ValueGeneration valueGeneration = bootProperty.getValueGenerationStrategy();
if ( valueConverter != null ) {
// we want to "decompose" the "type" into its various pieces as expected by the mapping
assert valueConverter.getRelationalJavaType() == resolution.getRelationalJavaType();
final BasicType<?> mappingBasicType = creationProcess.getCreationContext()
.getDomainModel()
.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( valueConverter.getRelationalJavaType(), resolution.getJdbcType() );
// final GeneratedValueResolver generatedValueResolver;
// if ( valueGeneration == null ) {
// generatedValueResolver = NoGeneratedValueResolver.INSTANCE;
// }
// else if ( valueGeneration.getValueGenerator() == null ) {
// // in-db generation
// }
return new BasicAttributeMapping(
attrName,
navigableRole,
stateArrayPosition,
attributeMetadataAccess,
fetchTiming,
fetchStyle,
tableExpression,
attrColumnName,
isAttrFormula,
null,
null,
columnDefinition,
length,
precision,
scale,
valueConverter,
mappingBasicType.getJdbcMapping(),
declaringType,
propertyAccess,
valueGeneration
);
}
else {
return new BasicAttributeMapping(
attrName,
navigableRole,
stateArrayPosition,
attributeMetadataAccess,
fetchTiming,
fetchStyle,
tableExpression,
attrColumnName,
isAttrFormula,
readExpr,
writeExpr,
columnDefinition,
length,
precision,
scale,
null,
attrType,
declaringType,
propertyAccess,
valueGeneration
);
}
return new BasicAttributeMapping(
attrName,
navigableRole,
stateArrayPosition,
attributeMetadataAccess,
fetchTiming,
fetchStyle,
tableExpression,
attrColumnName,
isAttrFormula,
readExpr,
writeExpr,
columnDefinition,
length,
precision,
scale,
attrType,
declaringType,
propertyAccess,
valueGeneration
);
}
@ -601,8 +557,6 @@ public class MappingModelCreationHelper {
indexDescriptor = new BasicValuedCollectionPart(
collectionDescriptor,
CollectionPart.Nature.INDEX,
// no converter
null,
selectableMapping
);
@ -653,8 +607,6 @@ public class MappingModelCreationHelper {
indexDescriptor = new BasicValuedCollectionPart(
collectionDescriptor,
CollectionPart.Nature.INDEX,
// no converter
null,
selectableMapping
);
@ -1350,7 +1302,6 @@ public class MappingModelCreationHelper {
return new BasicValuedCollectionPart(
collectionDescriptor,
CollectionPart.Nature.INDEX,
basicValue.resolve().getValueConverter(),
selectableMapping
);
}
@ -1435,7 +1386,6 @@ public class MappingModelCreationHelper {
return new BasicValuedCollectionPart(
collectionDescriptor,
CollectionPart.Nature.ELEMENT,
basicElement.resolve().getValueConverter(),
selectableMapping
);
}

View File

@ -274,16 +274,15 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
)
),
selectableMapping.getJdbcMapping().getJavaTypeDescriptor(),
selectableMapping.getJdbcMapping().getJdbcJavaType(),
fetchParent,
sqlAstCreationState.getCreationContext().getSessionFactory().getTypeConfiguration()
);
//noinspection unchecked
return new BasicResult<T>(
return new BasicResult<>(
sqlSelection.getValuesArrayPosition(),
null,
selectableMapping.getJdbcMapping().getJavaTypeDescriptor()
selectableMapping.getJdbcMapping()
);
}

View File

@ -20,5 +20,5 @@ import jakarta.persistence.metamodel.EmbeddableType;
* @author Steve Ebersole
*/
public interface EmbeddableDomainType<J>
extends ManagedDomainType<J>, EmbeddableType<J>, BindableType<J>, SqmExpressible<J> {
extends ManagedDomainType<J>, EmbeddableType<J>, SqmExpressible<J> {
}

View File

@ -6,11 +6,7 @@
*/
package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.query.BindableType;
import org.hibernate.query.ReturnableType;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmPath;
@ -21,7 +17,7 @@ import org.hibernate.spi.NavigablePath;
*
*/
public class AnyDiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
implements BindableType<D>, ReturnableType<D> {
implements ReturnableType<D> {
public AnyDiscriminatorSqmPathSource(

View File

@ -6,7 +6,6 @@
*/
package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.query.BindableType;
import org.hibernate.metamodel.UnsupportedMappingException;
import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
import org.hibernate.metamodel.model.domain.BasicDomainType;
@ -20,7 +19,7 @@ import static jakarta.persistence.metamodel.Bindable.BindableType.SINGULAR_ATTRI
/**
* @author Steve Ebersole
*/
public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> implements BindableType<J> {
public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
private final SqmPathSource<?> keyPathSource;
private final AnyDiscriminatorSqmPathSource discriminatorPathSource;

View File

@ -17,7 +17,6 @@ import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.query.ReturnableType;
import org.hibernate.metamodel.model.domain.TupleType;
import org.hibernate.query.BindableType;
import org.hibernate.query.sqm.SqmExpressible;
import org.hibernate.sql.ast.Clause;
import org.hibernate.type.descriptor.java.JavaType;
@ -27,7 +26,6 @@ import org.hibernate.type.descriptor.java.ObjectArrayJavaType;
* @author Christian Beikov
*/
public class ArrayTupleType implements TupleType<Object[]>,
BindableType<Object[]>,
ReturnableType<Object[]>,
MappingModelExpressible<Object[]> {

View File

@ -8,7 +8,6 @@ package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.query.ReturnableType;
import org.hibernate.query.BindableType;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
@ -19,7 +18,7 @@ import org.hibernate.query.sqm.tree.domain.SqmPath;
*/
public class BasicSqmPathSource<J>
extends AbstractSqmPathSource<J>
implements BindableType<J>, ReturnableType<J> {
implements ReturnableType<J> {
public BasicSqmPathSource(
String localPathName,

View File

@ -11,7 +11,6 @@ import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.ReturnableType;
import org.hibernate.query.BindableType;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmPath;
@ -22,7 +21,7 @@ import org.hibernate.query.sqm.tree.domain.SqmPath;
* @author Steve Ebersole
*/
public class DiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
implements BindableType<D>, ReturnableType<D> {
implements ReturnableType<D> {
private final EntityDomainType<?> entityDomainType;
private final EntityMappingType entityMapping;

View File

@ -13,7 +13,6 @@ import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.metamodel.model.domain.AbstractManagedType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.query.BindableType;
import org.hibernate.type.descriptor.java.JavaType;
/**
@ -25,7 +24,7 @@ import org.hibernate.type.descriptor.java.JavaType;
*/
public class EmbeddableTypeImpl<J>
extends AbstractManagedType<J>
implements EmbeddableDomainType<J>, BindableType<J>, Serializable {
implements EmbeddableDomainType<J>, Serializable {
private final boolean isDynamic;

View File

@ -6,7 +6,6 @@
*/
package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.query.BindableType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.SqmPathSource;
@ -18,7 +17,7 @@ import org.hibernate.query.sqm.tree.domain.SqmPath;
*/
public class EmbeddedSqmPathSource<J>
extends AbstractSqmPathSource<J>
implements CompositeSqmPathSource<J>, BindableType<J> {
implements CompositeSqmPathSource<J> {
public EmbeddedSqmPathSource(
String localPathName,

View File

@ -76,7 +76,7 @@ public class EntityTypeImpl<J>
.resolve( StandardBasicTypes.STRING );
}
this.discriminatorPathSource = new DiscriminatorSqmPathSource(
this.discriminatorPathSource = discriminatorType == null ? null : new DiscriminatorSqmPathSource(
discriminatorType,
this,
entityDescriptor

View File

@ -282,6 +282,13 @@ public class MappingMetamodelImpl implements MappingMetamodelImplementor, Metamo
modelCreationContext
);
entityPersisterMap.put( model.getEntityName(), cp );
// Also register the persister under the class name if available,
// otherwise the getEntityDescriptor(Class) won't work for entities with custom entity names
if ( model.getClassName() != null && !model.getClassName().equals( model.getEntityName() ) ) {
// But only if the class name is not registered already,
// as we can have the same class mapped to multiple entity names
entityPersisterMap.putIfAbsent( model.getClassName(), cp );
}
if ( cp.getConcreteProxyClass() != null
&& cp.getConcreteProxyClass().isInterface()

View File

@ -258,13 +258,6 @@ public abstract class AbstractCollectionPersister
private final CollectionSemantics<?,?> collectionSemantics;
private final BasicValueConverter elementConverter;
private final BasicValueConverter indexConverter;
// temporary
private final JdbcMapping convertedElementType;
private final JdbcMapping convertedIndexType;
@Deprecated(since = "6.0")
public AbstractCollectionPersister(
Collection collectionBootDescriptor,
@ -677,25 +670,6 @@ public abstract class AbstractCollectionPersister
.getPersistentCollectionRepresentationResolver()
.resolveRepresentation( collectionBootDescriptor );
if ( elementBootDescriptor instanceof BasicValue ) {
final BasicValue.Resolution<?> basicTypeResolution = ( (BasicValue) elementBootDescriptor ).resolve();
this.elementConverter = basicTypeResolution.getValueConverter();
this.convertedElementType = basicTypeResolution.getJdbcMapping();
}
else {
this.elementConverter = null;
this.convertedElementType = null;
}
if ( indexBootDescriptor instanceof BasicValue ) {
final BasicValue.Resolution<?> basicTypeResolution = ( (BasicValue) indexBootDescriptor ).resolve();
this.indexConverter = basicTypeResolution.getValueConverter();
this.convertedIndexType = basicTypeResolution.getJdbcMapping();
}
else {
this.indexConverter = null;
this.convertedIndexType = null;
}
if ( queryLoaderName != null ) {
// We must resolve the named query on-demand through the boot model because it isn't initialized yet
final NamedQueryMemento namedQueryMemento = factory.getQueryEngine().getNamedObjectRepository()
@ -992,12 +966,12 @@ public abstract class AbstractCollectionPersister
@Override
public BasicValueConverter<?,?> getElementConverter() {
return elementConverter;
return elementType instanceof JdbcMapping ? ( (JdbcMapping) elementType ).getValueConverter() : null;
}
@Override
public BasicValueConverter<?,?> getIndexConverter() {
return indexConverter;
return indexType instanceof JdbcMapping ? ( (JdbcMapping) indexType ).getValueConverter() : null;
}
/**
@ -1033,14 +1007,6 @@ public abstract class AbstractCollectionPersister
*/
protected int writeElement(PreparedStatement st, Object elt, int i, SharedSessionContractImplementor session)
throws HibernateException, SQLException {
// if ( elementConverter != null ) {
// //noinspection unchecked
// final Object converted = elementConverter.toRelationalValue( elt );
// convertedElementType.getJdbcValueBinder().bind( st, converted, i, session );
// }
// else {
// getElementType().nullSafeSet( st, elt, i, elementColumnIsSettable, session );
// }
getElementType().nullSafeSet( st, elt, i, elementColumnIsSettable, session );
return i + ArrayHelper.countTrue( elementColumnIsSettable );
@ -1052,15 +1018,7 @@ public abstract class AbstractCollectionPersister
*/
protected int writeIndex(PreparedStatement st, Object index, int i, SharedSessionContractImplementor session)
throws HibernateException, SQLException {
if ( indexConverter != null ) {
//noinspection unchecked
final Object converted = indexConverter.toRelationalValue( index );
//noinspection unchecked
convertedIndexType.getJdbcValueBinder().bind( st, converted, i, session );
}
else {
getIndexType().nullSafeSet( st, incrementIndexByBase( index ), i, indexColumnIsSettable, session );
}
getIndexType().nullSafeSet( st, incrementIndexByBase( index ), i, indexColumnIsSettable, session );
return i + ArrayHelper.countTrue( indexColumnIsSettable );
}
@ -1080,13 +1038,7 @@ public abstract class AbstractCollectionPersister
if ( elementIsPureFormula ) {
throw new AssertionFailure( "cannot use a formula-based element in the where condition" );
}
if ( elementConverter != null ) {
final Object converted = elementConverter.toRelationalValue( elt );
convertedElementType.getJdbcValueBinder().bind( st, converted, i, session );
}
else {
getElementType().nullSafeSet( st, elt, i, elementColumnIsInPrimaryKey, session );
}
getElementType().nullSafeSet( st, elt, i, elementColumnIsInPrimaryKey, session );
return i + elementColumnAliases.length;
}
@ -1098,13 +1050,7 @@ public abstract class AbstractCollectionPersister
if ( indexContainsFormula ) {
throw new AssertionFailure( "cannot use a formula-based index in the where condition" );
}
if ( indexConverter != null ) {
final Object converted = indexConverter.toRelationalValue( index );
convertedIndexType.getJdbcValueBinder().bind( st, converted, i, session );
}
else {
getIndexType().nullSafeSet( st, incrementIndexByBase( index ), i, session );
}
getIndexType().nullSafeSet( st, incrementIndexByBase( index ), i, session );
return i + indexColumnAliases.length;
}

View File

@ -2381,7 +2381,10 @@ public abstract class AbstractEntityPersister
}
private DiscriminatorMetadata buildTypeDiscriminatorMetadata() {
return () -> new DiscriminatorType<>( (BasicType<?>) getDiscriminatorType(), AbstractEntityPersister.this );
return () -> {
final BasicType<?> type = (BasicType<?>) getDiscriminatorType();
return type == null ? null : new DiscriminatorType<>( type, AbstractEntityPersister.this );
};
}
public static String generateTableAlias(String rootAlias, int tableNumber) {

View File

@ -84,10 +84,9 @@ class DiscriminatorHelper {
PersistentClass persistentClass,
Dialect dialect,
WrapperOptions wrapperOptions) {
JavaType<T> javaType = discriminatorType.getJavaTypeDescriptor();
final JavaType<T> javaType = discriminatorType.getJavaTypeDescriptor();
try {
return discriminatorType.getJdbcType()
.getJdbcLiteralFormatter( javaType )
return discriminatorType.getJdbcLiteralFormatter()
.toJdbcLiteral(
javaType.fromString( persistentClass.getDiscriminatorValue() ),
dialect,

View File

@ -8,7 +8,6 @@ package org.hibernate.persister.entity;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.Objects;
@ -20,15 +19,16 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.type.AbstractType;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.ClassJavaType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.StringJavaType;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.hibernate.type.descriptor.jdbc.JdbcType;
/**
@ -36,7 +36,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcType;
*
* @author Steve Ebersole
*/
public class DiscriminatorType<T> extends AbstractType implements BasicType<T>, ValueExtractor<T>, ValueBinder<T> {
public class DiscriminatorType<T> extends AbstractType implements BasicType<T>, BasicValueConverter<T, Object> {
private final BasicType<Object> underlyingType;
private final Loadable persister;
@ -50,8 +50,60 @@ public class DiscriminatorType<T> extends AbstractType implements BasicType<T>,
}
@Override
public JdbcMapping getJdbcMapping() {
return getUnderlyingType().getJdbcMapping();
public BasicValueConverter<T, ?> getValueConverter() {
return this;
}
@Override
public JavaType<?> getJdbcJavaType() {
return underlyingType.getJdbcJavaType();
}
@Override
public T toDomainValue(Object discriminatorValue) {
if ( discriminatorValue == null ) {
return null;
}
final String entityName = persister.getSubclassForDiscriminatorValue( discriminatorValue );
if ( entityName == null ) {
throw new HibernateException( "Unable to resolve discriminator value [" + discriminatorValue + "] to entity name" );
}
final EntityPersister entityPersister = persister.getFactory()
.getRuntimeMetamodels()
.getMappingMetamodel()
.getEntityDescriptor( entityName );
//noinspection unchecked
return entityPersister.getRepresentationStrategy().getMode() == RepresentationMode.POJO
? (T) entityPersister.getJavaType().getJavaTypeClass()
: (T) entityName;
}
@Override
public Object toRelationalValue(T domainForm) {
if ( domainForm == null ) {
return null;
}
final MappingMetamodelImplementor mappingMetamodel = persister.getFactory()
.getRuntimeMetamodels()
.getMappingMetamodel();
final Loadable loadable;
if ( domainForm instanceof Class<?> ) {
loadable = (Loadable) mappingMetamodel.getEntityDescriptor( (Class<?>) domainForm );
}
else {
loadable = (Loadable) mappingMetamodel.getEntityDescriptor( (String) domainForm );
}
return loadable.getDiscriminatorValue();
}
@Override
public JavaType<T> getDomainJavaType() {
return getExpressibleJavaType();
}
@Override
public JavaType<Object> getRelationalJavaType() {
return underlyingType.getExpressibleJavaType();
}
@Override
@ -78,43 +130,14 @@ public class DiscriminatorType<T> extends AbstractType implements BasicType<T>,
public T extract(CallableStatement statement, int paramIndex, SharedSessionContractImplementor session)
throws SQLException {
final Object discriminatorValue = underlyingType.extract( statement, paramIndex, session );
return (T) get( discriminatorValue, session );
return toDomainValue( discriminatorValue );
}
@Override
public T extract(CallableStatement statement, String paramName, SharedSessionContractImplementor session)
throws SQLException {
final Object discriminatorValue = underlyingType.extract( statement, paramName, session );
return (T) get( discriminatorValue, session );
}
@Override
public T extract(ResultSet rs, int paramIndex, WrapperOptions options) throws SQLException {
final Object discriminatorValue = underlyingType.getJdbcValueExtractor().extract( rs, paramIndex, options );
return (T) get( discriminatorValue, options.getSession() );
}
@Override
public T extract(CallableStatement statement, int paramIndex, WrapperOptions options) throws SQLException {
final Object discriminatorValue = underlyingType.getJdbcValueExtractor().extract( statement, paramIndex, options );
return (T) get( discriminatorValue, options.getSession() );
}
@Override
public T extract(CallableStatement statement, String paramName, WrapperOptions options) throws SQLException {
final Object discriminatorValue = underlyingType.getJdbcValueExtractor().extract( statement, paramName, options );
return (T) get( discriminatorValue, options.getSession() );
}
private Object get(Object discriminatorValue, SharedSessionContractImplementor session) {
final String entityName = persister.getSubclassForDiscriminatorValue( discriminatorValue );
if ( entityName == null ) {
throw new HibernateException( "Unable to resolve discriminator value [" + discriminatorValue + "] to entity name" );
}
final EntityPersister entityPersister = session.getEntityPersister( entityName, null );
return entityPersister.getRepresentationStrategy().getMode() == RepresentationMode.POJO
? entityPersister.getJavaType().getJavaTypeClass()
: entityName;
return toDomainValue( discriminatorValue );
}
@Override
@ -133,31 +156,7 @@ public class DiscriminatorType<T> extends AbstractType implements BasicType<T>,
Object value,
int index,
SharedSessionContractImplementor session) throws HibernateException, SQLException {
final Loadable loadable = (Loadable) session.getFactory()
.getRuntimeMetamodels()
.getMappingMetamodel()
.getEntityDescriptor( (Class<?>) value );
underlyingType.nullSafeSet(st, loadable.getDiscriminatorValue(), index, session);
}
@Override
public void bind(PreparedStatement st, T value, int index, WrapperOptions options) throws SQLException {
final SessionFactoryImplementor factory = options.getSession().getFactory();
final Loadable loadable = (Loadable) factory
.getRuntimeMetamodels()
.getMappingMetamodel()
.getEntityDescriptor( (Class<?>) value );
underlyingType.getJdbcValueBinder().bind( st, loadable.getDiscriminatorValue(), index, options );
}
@Override
public void bind(CallableStatement st, T value, String name, WrapperOptions options) throws SQLException {
final SessionFactoryImplementor factory = options.getSession().getFactory();
final Loadable loadable = (Loadable) factory
.getRuntimeMetamodels()
.getMappingMetamodel()
.getEntityDescriptor( (Class<?>) value );
underlyingType.getJdbcValueBinder().bind( st, loadable.getDiscriminatorValue(), name, options );
underlyingType.nullSafeSet( st, toRelationalValue( (T) value ), index, session);
}
@Override
@ -190,6 +189,10 @@ public class DiscriminatorType<T> extends AbstractType implements BasicType<T>,
return Objects.equals( old, current );
}
@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
return toRelationalValue( (T) value );
}
// simple delegation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -233,12 +236,17 @@ public class DiscriminatorType<T> extends AbstractType implements BasicType<T>,
@Override
public ValueExtractor<T> getJdbcValueExtractor() {
return this;
return (ValueExtractor<T>) underlyingType.getJdbcValueExtractor();
}
@Override
public ValueBinder<T> getJdbcValueBinder() {
return this;
return (ValueBinder<T>) underlyingType.getJdbcValueBinder();
}
@Override
public JdbcLiteralFormatter getJdbcLiteralFormatter() {
return underlyingType.getJdbcLiteralFormatter();
}
@Override

View File

@ -745,7 +745,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
);
}
final BasicType<?> discriminatorType = (BasicType<?>) getDiscriminatorType();
final BasicType<?> discriminatorType = (BasicType<?>) getDiscriminatorMapping().getJdbcMapping();
final Expression sqlExpression = sqlExpressionResolver.resolveSqlExpression(
columnReferenceKey,
sqlAstProcessingState -> new ColumnReference(

View File

@ -638,11 +638,19 @@ public class ProcedureCallImpl<R>
throw new IllegalArgumentException( "The parameter at position [" + parameter + "] was not set! You need to call the setParameter method." );
}
}
final JdbcMapping parameterType = (JdbcMapping) registration.getParameterType();
final Object bindValue;
if ( parameterType.getValueConverter() == null ) {
bindValue = binding.getBindValue();
}
else {
bindValue = parameterType.getValueConverter().toRelationalValue( binding.getBindValue() );
}
jdbcParameterBindings.addBinding(
(JdbcParameter) registration.getParameterBinder(),
new JdbcParameterBindingImpl(
(JdbcMapping) registration.getParameterType(),
binding.getBindValue()
parameterType,
bindValue
)
);
}

View File

@ -29,6 +29,10 @@ public interface BindableType<J> {
*/
Class<J> getBindableJavaType();
default boolean isInstance(J value) {
return getBindableJavaType().isInstance( value );
}
static <T> BindableType<? extends T> parameterType(Class<T> type) {
throw new NotYetImplementedFor6Exception( "BindableType#parameterType" );
}

View File

@ -171,12 +171,10 @@ public class AnonymousTupleBasicValuedModelPart implements ModelPart, MappingTyp
creationState.getSqlAstCreationState()
);
//noinspection unchecked
return new BasicResult(
return new BasicResult<>(
sqlSelection.getValuesArrayPosition(),
resultVariable,
getJavaType(),
null,
jdbcMapping,
navigablePath
);
}
@ -201,7 +199,7 @@ public class AnonymousTupleBasicValuedModelPart implements ModelPart, MappingTyp
);
return expressionResolver.resolveSqlSelection(
expression,
getJdbcMapping().getJavaTypeDescriptor(),
getJdbcMapping().getJdbcJavaType(),
fetchParent,
creationState.getCreationContext().getSessionFactory().getTypeConfiguration()
);
@ -234,7 +232,6 @@ public class AnonymousTupleBasicValuedModelPart implements ModelPart, MappingTyp
fetchParent,
fetchablePath,
this,
null,
fetchTiming,
creationState
);

View File

@ -2152,7 +2152,10 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
);
}
private <T> SqmExpression<T> createDiscriminatorValue(AnyDiscriminatorSqmPath anyDiscriminatorTypeSqmPath, HqlParser.ExpressionContext valueExpressionContext) {
private <T> SqmExpression<T> createDiscriminatorValue(
AnyDiscriminatorSqmPath anyDiscriminatorTypeSqmPath,
HqlParser.ExpressionContext valueExpressionContext) {
//noinspection unchecked
final SqmPath<T> discriminatorSqmPath = anyDiscriminatorTypeSqmPath.getLhs();
final EntityDomainType<T> entityWithDiscriminator = creationContext.getJpaMetamodel()
.entity( discriminatorSqmPath.findRoot().getNavigablePath().getLocalName() );

View File

@ -13,12 +13,12 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.query.BindableType;
import org.hibernate.query.QueryParameter;
import org.hibernate.query.spi.QueryParameterBinding;
import org.hibernate.query.spi.QueryParameterBindingValidator;
import org.hibernate.query.sqm.SqmExpressible;
import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
import org.hibernate.type.descriptor.java.CoercionException;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.TemporalJavaType;
@ -143,9 +143,6 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
final SqmExpressible<? extends T> sqmExpressible = parameterType.resolveExpressible( sessionFactory );
assert sqmExpressible != null;
if ( sqmExpressible instanceof AttributeConverterTypeAdapter ) {
return value;
}
return sqmExpressible.getExpressibleJavaType().coerce( value, this );
}
@ -321,7 +318,8 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
@Override @SuppressWarnings("unchecked")
public boolean setType(MappingModelExpressible<T> type) {
this.type = type;
if ( bindType == null || bindType.getBindableJavaType() == Object.class ) {
// If the bind type is undetermined or the given type is a model part, then we try to apply a new bind type
if ( bindType == null || bindType.getBindableJavaType() == Object.class || type instanceof ModelPart ) {
if ( type instanceof BindableType<?> ) {
final boolean changed = bindType != null && type != bindType;
this.bindType = (BindableType<T>) type;

View File

@ -337,7 +337,11 @@ public class ResultSetMappingImpl implements ResultSetMapping {
final ResultSetMappingSqlSelection sqlSelection = new ResultSetMappingSqlSelection( valuesArrayPosition, (BasicValuedMapping) jdbcMapping );
sqlSelectionConsumer.accept( sqlSelection );
return new BasicResult( valuesArrayPosition, name, jdbcMapping.getJavaTypeDescriptor() );
return new BasicResult(
valuesArrayPosition,
name,
jdbcMapping
);
}
@Override

View File

@ -91,7 +91,7 @@ public class CompleteFetchBuilderEmbeddableValuedModelPart
return new ResultSetMappingSqlSelection( valuesArrayPosition, selectableMapping.getJdbcMapping() );
}
),
modelPart.getJavaType(),
selectableMapping.getJdbcMapping().getJdbcJavaType(),
null,
creationStateImpl.getSessionFactory().getTypeConfiguration()
);

View File

@ -95,7 +95,7 @@ public class CompleteFetchBuilderEntityValuedModelPart
return new ResultSetMappingSqlSelection( valuesArrayPosition, selectableMapping.getJdbcMapping() );
}
),
modelPart.getJavaType(),
selectableMapping.getJdbcMapping().getJdbcJavaType(),
null,
creationStateImpl.getSessionFactory().getTypeConfiguration()
);

View File

@ -86,16 +86,15 @@ public class CompleteResultBuilderBasicModelPart
return new ResultSetMappingSqlSelection( valuesArrayPosition, modelPart );
}
),
modelPart.getJavaType(),
modelPart.getJdbcMapping().getJdbcJavaType(),
null,
creationStateImpl.getSessionFactory().getTypeConfiguration()
);
//noinspection unchecked
return new BasicResult(
return new BasicResult<>(
sqlSelection.getValuesArrayPosition(),
columnAlias,
modelPart.getJavaType()
modelPart.getJdbcMapping()
);
}

View File

@ -131,7 +131,7 @@ public class CompleteResultBuilderBasicValuedConverted<O,R> implements CompleteR
return new ResultSetMappingSqlSelection( valuesArrayPosition, underlyingMapping );
}
),
valueConverter.getDomainJavaType(),
valueConverter.getRelationalJavaType(),
null,
sessionFactory.getTypeConfiguration()
);

View File

@ -11,6 +11,7 @@ import java.util.function.BiFunction;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.query.results.DomainResultCreationStateImpl;
import org.hibernate.query.results.ResultBuilder;
import org.hibernate.query.results.ResultsHelper;
@ -142,10 +143,11 @@ public class CompleteResultBuilderBasicValuedStandard implements CompleteResultB
sessionFactory.getTypeConfiguration()
);
return new BasicResult<>(
final JdbcMapping jdbcMapping = sqlSelection.getExpressionType().getJdbcMappings().get( 0 );
return new BasicResult(
sqlSelection.getValuesArrayPosition(),
columnName,
sqlSelection.getExpressionType().getJdbcMappings().get( 0 ).getMappedJavaType()
jdbcMapping
);
}

View File

@ -167,7 +167,7 @@ public class CompleteResultBuilderCollectionStandard implements CompleteResultBu
return new ResultSetMappingSqlSelection( valuesArrayPosition, basicType );
}
),
selectableMapping.getJdbcMapping().getMappedJavaType(),
selectableMapping.getJdbcMapping().getJdbcJavaType(),
null,
creationStateImpl.getSessionFactory().getTypeConfiguration()
);

View File

@ -246,7 +246,7 @@ public class DynamicFetchBuilderLegacy implements DynamicFetchBuilder, NativeQue
return new ResultSetMappingSqlSelection( valuesArrayPosition, jdbcMapping );
}
),
jdbcMapping.getMappedJavaType(),
jdbcMapping.getJdbcJavaType(),
null,
domainResultCreationState.getSqlAstCreationState().getCreationContext().getSessionFactory().getTypeConfiguration()
);

View File

@ -96,7 +96,7 @@ public class DynamicFetchBuilderStandard
return new ResultSetMappingSqlSelection( valuesArrayPosition, selectableMapping.getJdbcMapping() );
}
),
selectableMapping.getJdbcMapping().getMappedJavaType(),
selectableMapping.getJdbcMapping().getJdbcJavaType(),
null,
domainResultCreationState.getSqlAstCreationState()
.getCreationContext()

View File

@ -88,7 +88,7 @@ public class DynamicResultBuilderAttribute implements DynamicResultBuilder, Nati
return new ResultSetMappingSqlSelection( valuesArrayPosition, attributeMapping );
}
),
attributeMapping.getJavaType(),
attributeMapping.getJdbcMapping().getJdbcJavaType(),
null,
domainResultCreationState.getSqlAstCreationState()
.getCreationContext()
@ -99,8 +99,7 @@ public class DynamicResultBuilderAttribute implements DynamicResultBuilder, Nati
return new BasicResult<>(
sqlSelection.getValuesArrayPosition(),
columnAlias,
attributeMapping.getJavaType(),
attributeMapping.getValueConverter()
attributeMapping.getJdbcMapping()
);
}

View File

@ -126,7 +126,7 @@ public class DynamicResultBuilderBasicConverted<O,R> implements DynamicResultBui
return new ResultSetMappingSqlSelection( valuesArrayPosition, (BasicValuedMapping) basicType );
}
),
basicValueConverter.getDomainJavaType(),
basicValueConverter.getRelationalJavaType(),
null,
typeConfiguration
);

View File

@ -9,6 +9,8 @@ package org.hibernate.query.results.dynamic;
import java.util.Objects;
import java.util.function.BiFunction;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.query.NativeQuery;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.BasicValuedMapping;
@ -154,16 +156,23 @@ public class DynamicResultBuilderBasicStandard implements DynamicResultBuilderBa
);
final JavaType<?> javaType;
final JavaType<?> jdbcJavaType;
final BasicValueConverter<?, ?> converter;
if ( explicitJavaType != null ) {
javaType = explicitJavaType;
jdbcJavaType = explicitJavaType;
converter = null;
}
else {
javaType = expression.getExpressionType().getJdbcMappings().get( 0 ).getMappedJavaType();
final JdbcMapping jdbcMapping = expression.getExpressionType().getJdbcMappings().get( 0 );
javaType = jdbcMapping.getMappedJavaType();
jdbcJavaType = jdbcMapping.getJdbcJavaType();
converter = jdbcMapping.getValueConverter();
}
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
expression,
javaType,
jdbcJavaType,
null,
sessionFactory.getTypeConfiguration()
);
@ -171,7 +180,7 @@ public class DynamicResultBuilderBasicStandard implements DynamicResultBuilderBa
// StandardRowReader expects there to be a JavaType as part of the ResultAssembler.
assert javaType != null;
return new BasicResult<>( sqlSelection.getValuesArrayPosition(), resultAlias, javaType );
return new BasicResult( sqlSelection.getValuesArrayPosition(), resultAlias, javaType, converter );
}
@Override

View File

@ -289,7 +289,7 @@ public class DynamicResultBuilderEntityStandard
return new ResultSetMappingSqlSelection( valuesArrayPosition, jdbcMapping );
}
),
jdbcMapping.getMappedJavaType(),
jdbcMapping.getJdbcJavaType(),
null,
domainResultCreationState.getSqlAstCreationState().getCreationContext().getSessionFactory().getTypeConfiguration()
);

View File

@ -110,7 +110,7 @@ public class ImplicitFetchBuilderBasic implements ImplicitFetchBuilder, BasicVal
final SqlSelection sqlSelection = creationStateImpl.resolveSqlSelection(
expression,
fetchable.getJavaType(),
fetchable.getJdbcMapping().getJdbcJavaType(),
parent,
domainResultCreationState.getSqlAstCreationState()
.getCreationContext()
@ -118,20 +118,11 @@ public class ImplicitFetchBuilderBasic implements ImplicitFetchBuilder, BasicVal
.getTypeConfiguration()
);
final BasicValueConverter<?, ?> valueConverter;
if ( fetchable instanceof ConvertibleModelPart ) {
valueConverter = ( (ConvertibleModelPart) fetchable ).getValueConverter();
}
else {
valueConverter = null;
}
return new BasicFetch<>(
sqlSelection.getValuesArrayPosition(),
parent,
fetchPath,
fetchable,
valueConverter,
FetchTiming.IMMEDIATE,
domainResultCreationState
);

View File

@ -13,7 +13,6 @@ import java.util.Date;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.BindableType;
import org.hibernate.query.sqm.SqmExpressible;
import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
import org.hibernate.type.descriptor.java.JavaType;
import jakarta.persistence.TemporalType;
@ -42,15 +41,6 @@ public class QueryParameterBindingValidator {
return;
}
if ( paramType instanceof AttributeConverterTypeAdapter ) {
final AttributeConverterTypeAdapter<?> converterTypeAdapter = (AttributeConverterTypeAdapter<?>) paramType;
final JavaType<?> domainJtd = converterTypeAdapter.getDomainJtd();
if ( domainJtd.getJavaTypeClass().isInstance( bind ) ) {
return;
}
}
final Class<?> parameterJavaType;
final SqmExpressible<?> sqmExpressible = paramType.resolveExpressible( sessionFactory );
if ( paramType.getBindableJavaType() != null ) {

View File

@ -25,6 +25,11 @@ public interface SqmExpressible<J> extends BindableType<J> {
*/
JavaType<J> getExpressibleJavaType();
@Override
default boolean isInstance(J value) {
return getExpressibleJavaType().isInstance( value );
}
@Override
default SqmExpressible<J> resolveExpressible(SessionFactoryImplementor sessionFactory) {
return this;

View File

@ -17,6 +17,7 @@ import org.hibernate.mapping.Table;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
import org.hibernate.metamodel.mapping.SqlExpressible;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.query.ReturnableType;
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
import org.hibernate.sql.ast.SqlAstTranslator;
@ -101,17 +102,29 @@ public class SelfRenderingFunctionSqlAstExpression
public DomainResult createDomainResult(
String resultVariable,
DomainResultCreationState creationState) {
final JdbcMapping jdbcMapping = getJdbcMapping();
final JavaType<?> jdbcJavaType;
final BasicValueConverter<?, ?> converter;
if ( jdbcMapping != null ) {
jdbcJavaType = jdbcMapping.getJdbcJavaType();
converter = jdbcMapping.getValueConverter();
}
else {
jdbcJavaType = type.getExpressibleJavaType();
converter = null;
}
return new BasicResult(
creationState.getSqlAstCreationState().getSqlExpressionResolver()
.resolveSqlSelection(
this,
type.getExpressibleJavaType(),
jdbcJavaType,
null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()
)
.getValuesArrayPosition(),
resultVariable,
type.getExpressibleJavaType()
type.getExpressibleJavaType(),
converter
);
}
@ -181,9 +194,17 @@ public class SelfRenderingFunctionSqlAstExpression
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
final JdbcMapping jdbcMapping = getJdbcMapping();
final JavaType<?> jdbcJavaType;
if ( jdbcMapping != null ) {
jdbcJavaType = jdbcMapping.getJdbcJavaType();
}
else {
jdbcJavaType = type.getExpressibleJavaType();
}
sqlExpressionResolver.resolveSqlSelection(
this,
type.getExpressibleJavaType(),
jdbcJavaType,
null,
sqlAstCreationState.getCreationContext().getMappingMetamodel().getTypeConfiguration()
);

View File

@ -1001,7 +1001,15 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
}
final SqmExpressible<T> expressible = resolveInferredType( value, typeInferenceSource, getTypeConfiguration() );
return new SqmLiteral<>( value, expressible, this );
if ( expressible.getExpressibleJavaType().isInstance( value ) ) {
return new SqmLiteral<>( value, expressible, this );
}
// Just like in HQL, we allow coercion of literal values to the inferred type
return new SqmLiteral<>(
expressible.getExpressibleJavaType().coerce( value, this::getTypeConfiguration ),
expressible,
this
);
}
private static <T> SqmExpressible<T> resolveInferredType(
@ -1551,13 +1559,38 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
return literal( value, typeInferenceSource );
}
return new ValueBindJpaCriteriaParameter<>(
resolveInferredParameterType( value, typeInferenceSource, getTypeConfiguration() ),
final BindableType<T> bindableType = resolveInferredParameterType(
value,
typeInferenceSource,
getTypeConfiguration()
);
if ( bindableType == null || isInstance( bindableType, value ) ) {
return new ValueBindJpaCriteriaParameter<>(
bindableType,
value,
this
);
}
final SqmExpressible<T> expressible = bindableType.resolveExpressible( getTypeConfiguration().getSessionFactory() );
return new ValueBindJpaCriteriaParameter<>(
bindableType,
expressible.getExpressibleJavaType().coerce( value, this::getTypeConfiguration ),
this
);
}
private <T> boolean isInstance(BindableType<T> bindableType, T value) {
if ( bindableType instanceof SqmExpressible<?> ) {
return ( (SqmExpressible<T>) bindableType ).getExpressibleJavaType().isInstance( value );
}
if ( bindableType.getBindableJavaType().isInstance( value ) ) {
return true;
}
return bindableType.resolveExpressible( getTypeConfiguration().getSessionFactory() )
.getExpressibleJavaType()
.isInstance( value );
}
private static <T> BindableType<T> resolveInferredParameterType(
T value,
SqmExpression<? extends T> typeInferenceSource,

View File

@ -23,6 +23,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.Bindable;
import org.hibernate.metamodel.mapping.ConvertibleModelPart;
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
@ -56,7 +57,6 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
import org.hibernate.type.spi.TypeConfiguration;
/**
@ -223,10 +223,10 @@ public class SqmUtil {
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
final List<JdbcParameter> jdbcParams = jdbcParamsBinds.get( i );
parameterType.forEachJdbcType(
(position, jdbcType) -> {
(position, jdbcMapping) -> {
jdbcParameterBindings.addBinding(
jdbcParams.get( position ),
new JdbcParameterBindingImpl( jdbcType, null )
new JdbcParameterBindingImpl( jdbcMapping, null )
);
}
);
@ -285,37 +285,35 @@ public class SqmUtil {
}
}
else {
if ( domainParamBinding.getType() instanceof AttributeConverterTypeAdapter
|| domainParamBinding.getType() instanceof ConvertibleModelPart ) {
final BasicValueConverter valueConverter;
final JdbcMapping jdbcMapping;
final JdbcMapping jdbcMapping;
final BasicValueConverter valueConverter;
if ( domainParamBinding.getType() instanceof JdbcMapping ) {
jdbcMapping = (JdbcMapping) domainParamBinding.getType();
valueConverter = jdbcMapping.getValueConverter();
}
else if ( domainParamBinding.getBindType() instanceof BasicValuedModelPart ) {
jdbcMapping = ( (BasicValuedModelPart) domainParamBinding.getType() ).getJdbcMapping();
valueConverter = jdbcMapping.getValueConverter();
}
else {
jdbcMapping = null;
valueConverter = null;
}
if ( domainParamBinding.getType() instanceof AttributeConverterTypeAdapter ) {
final AttributeConverterTypeAdapter<?> adapter = (AttributeConverterTypeAdapter<?>) domainParamBinding.getType();
valueConverter = adapter.getAttributeConverter();
jdbcMapping = adapter.getJdbcMapping();
}
else {
final ConvertibleModelPart convertibleModelPart = (ConvertibleModelPart) domainParamBinding.getType();
valueConverter = convertibleModelPart.getValueConverter();
jdbcMapping = convertibleModelPart.getJdbcMapping();
if ( valueConverter != null ) {
final Object convertedValue = valueConverter.toRelationalValue( domainParamBinding.getBindValue() );
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
final List<JdbcParameter> jdbcParams = jdbcParamsBinds.get( i );
assert jdbcParams.size() == 1;
final JdbcParameter jdbcParameter = jdbcParams.get( 0 );
jdbcParameterBindings.addBinding(
jdbcParameter,
new JdbcParameterBindingImpl( jdbcMapping, convertedValue )
);
}
if ( valueConverter != null ) {
final Object convertedValue = valueConverter.toRelationalValue( domainParamBinding.getBindValue() );
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
final List<JdbcParameter> jdbcParams = jdbcParamsBinds.get( i );
assert jdbcParams.size() == 1;
final JdbcParameter jdbcParameter = jdbcParams.get( 0 );
jdbcParameterBindings.addBinding(
jdbcParameter,
new JdbcParameterBindingImpl( jdbcMapping, convertedValue )
);
}
continue;
}
continue;
}
final Object bindValue = domainParamBinding.getBindValue();

View File

@ -111,7 +111,7 @@ public class MatchingIdSelectionHelper {
new BasicResult<>(
selection.getValuesArrayPosition(),
null,
jdbcMapping.getJavaTypeDescriptor()
jdbcMapping
)
);
}
@ -270,7 +270,7 @@ public class MatchingIdSelectionHelper {
new BasicResult<>(
selection.getValuesArrayPosition(),
null,
jdbcMapping.getJavaTypeDescriptor()
jdbcMapping
)
);
}

View File

@ -170,7 +170,7 @@ public abstract class AbstractCteMutationHandler extends AbstractMutationHandler
new BasicResult<>(
0,
null,
( (SqlExpressible) count).getJdbcMapping().getJavaTypeDescriptor()
( (SqlExpressible) count).getJdbcMapping()
)
);
querySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl( 1, 0, count ) );

View File

@ -91,7 +91,7 @@ public class CteDeleteHandler extends AbstractCteMutationHandler implements Dele
new BasicResult<>(
selection.getValuesArrayPosition(),
null,
jdbcMapping.getJavaTypeDescriptor()
jdbcMapping
)
);
}

View File

@ -645,10 +645,10 @@ public class CteInsertHandler implements InsertHandler {
final Expression count = createCountStar( factory, sqmConverter );
domainResults.add(
new BasicResult(
new BasicResult<>(
0,
null,
( (SqlExpressible) count).getJdbcMapping().getJavaTypeDescriptor()
( (SqlExpressible) count).getJdbcMapping()
)
);
querySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl( 1, 0, count ) );

View File

@ -368,7 +368,6 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio
null,
null,
identifierMapping,
null,
FetchTiming.IMMEDIATE,
null
)

View File

@ -63,7 +63,6 @@ import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.Bindable;
import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.mapping.ConvertibleModelPart;
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
@ -300,7 +299,6 @@ import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression;
import org.hibernate.sql.ast.tree.expression.CastTarget;
import org.hibernate.sql.ast.tree.expression.Collation;
import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.expression.ConvertedQueryLiteral;
import org.hibernate.sql.ast.tree.expression.Distinct;
import org.hibernate.sql.ast.tree.expression.Duration;
import org.hibernate.sql.ast.tree.expression.DurationUnit;
@ -380,9 +378,10 @@ import org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiati
import org.hibernate.sql.results.internal.SqlSelectionImpl;
import org.hibernate.sql.results.internal.StandardEntityGraphTraversalStateImpl;
import org.hibernate.type.BasicType;
import org.hibernate.type.CustomType;
import org.hibernate.type.EnumType;
import org.hibernate.type.JavaObjectType;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.java.BasicJavaType;
import org.hibernate.type.descriptor.java.EnumJavaType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.TemporalJavaType;
@ -4679,53 +4678,46 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
return new SqlTuple( expressions, mappingModelExpressible);
}
final MappingModelExpressible<?> inferableExpressible = resolveInferredType();
final MappingModelExpressible<?> inferableExpressible = getInferredValueMapping();
if ( inferableExpressible instanceof ConvertibleModelPart ) {
final ConvertibleModelPart convertibleModelPart = (ConvertibleModelPart) inferableExpressible;
if ( convertibleModelPart.getValueConverter() != null ) {
return new QueryLiteral<>(
literal.getLiteralValue(),
convertibleModelPart
);
}
}
// Special case for when we create an entity literal through the JPA CriteriaBuilder.literal API
else if ( inferableExpressible instanceof EntityDiscriminatorMapping ) {
final EntityDiscriminatorMapping discriminatorMapping = (EntityDiscriminatorMapping) inferableExpressible;
final Object literalValue = literal.getLiteralValue();
final EntityPersister mappingDescriptor;
if ( literalValue instanceof Class<?> ) {
mappingDescriptor = creationContext.getSessionFactory()
.getRuntimeMetamodels()
.getMappingMetamodel()
.getEntityDescriptor( (Class<?>) literalValue );
}
else {
final JavaType<?> javaType = discriminatorMapping.getJdbcMapping().getJavaTypeDescriptor();
final Object discriminatorValue;
if ( javaType.getJavaTypeClass().isInstance( literalValue ) ) {
discriminatorValue = literalValue;
if ( inferableExpressible instanceof BasicValuedMapping ) {
final BasicValuedMapping basicValuedMapping = (BasicValuedMapping) inferableExpressible;
final BasicValueConverter valueConverter = basicValuedMapping.getJdbcMapping().getValueConverter();
if ( valueConverter != null ) {
final Object value = literal.getLiteralValue();
final Object sqlLiteralValue;
// For converted query literals, we support both, the domain and relational java type
if ( value == null || valueConverter.getDomainJavaType().getJavaTypeClass().isInstance( value ) ) {
sqlLiteralValue = valueConverter.toRelationalValue( value );
}
else if ( literalValue instanceof CharSequence ) {
discriminatorValue = javaType.fromString( (CharSequence) literalValue );
else if ( valueConverter.getRelationalJavaType().getJavaTypeClass().isInstance( value ) ) {
sqlLiteralValue = value;
}
else if ( creationContext.getSessionFactory().getJpaMetamodel().getJpaCompliance().isLoadByIdComplianceEnabled() ) {
discriminatorValue = literalValue;
else if ( basicValuedMapping instanceof EntityDiscriminatorMapping ) {
// Special case when passing the discriminator value as e.g. string literal,
// but the expected relational type is Character.
// In this case, we use wrap to transform the value to the correct type
sqlLiteralValue = valueConverter.getRelationalJavaType().wrap(
value,
creationContext.getSessionFactory().getWrapperOptions()
);
}
else {
discriminatorValue = javaType.coerce( literalValue, null );
throw new SqlTreeCreationException(
String.format(
Locale.ROOT,
"QueryLiteral type [`%s`] did not match domain Java-type [`%s`] nor JDBC Java-type [`%s`]",
value.getClass(),
valueConverter.getDomainJavaType().getJavaTypeClass().getName(),
valueConverter.getRelationalJavaType().getJavaTypeClass().getName()
)
);
}
final String entityName = discriminatorMapping.getConcreteEntityNameForDiscriminatorValue(
discriminatorValue
return new QueryLiteral<>(
sqlLiteralValue,
basicValuedMapping
);
mappingDescriptor = creationContext.getSessionFactory()
.getRuntimeMetamodels()
.getMappingMetamodel()
.getEntityDescriptor( entityName );
}
return new EntityTypeLiteral( mappingDescriptor );
}
@ -6298,25 +6290,34 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
@Override
public Object visitEnumLiteral(SqmEnumLiteral<?> sqmEnumLiteral) {
final BasicValuedMapping inferrableType = (BasicValuedMapping) resolveInferredType();
if ( inferrableType instanceof ConvertibleModelPart ) {
final ConvertibleModelPart inferredPart = (ConvertibleModelPart) inferrableType;
final BasicValueConverter<Enum<?>,?> valueConverter = inferredPart.getValueConverter();
final Object jdbcValue = valueConverter.toRelationalValue( sqmEnumLiteral.getEnumValue() );
return new QueryLiteral<>( jdbcValue, inferredPart );
if ( inferrableType != null ) {
final BasicValueConverter<Enum<?>,?> valueConverter = (BasicValueConverter<Enum<?>, ?>) inferrableType.getJdbcMapping().getValueConverter();
final Object jdbcValue;
if ( valueConverter == null ) {
jdbcValue = sqmEnumLiteral.getEnumValue();
}
else {
jdbcValue = valueConverter.toRelationalValue( sqmEnumLiteral.getEnumValue() );
}
return new QueryLiteral<>( jdbcValue, inferrableType );
}
// This can only happen when selecting an enum literal, in which case we default to ordinal encoding
final EnumJavaType<?> enumJtd = sqmEnumLiteral.getExpressibleJavaType();
final JdbcType jdbcType = getTypeConfiguration().getJdbcTypeRegistry()
.getDescriptor( SqlTypes.SMALLINT );
final BasicJavaType<Number> relationalJtd = (BasicJavaType) getTypeConfiguration()
.getJavaTypeRegistry()
.getDescriptor( Integer.class );
final BasicType<?> jdbcMappingType = getTypeConfiguration().getBasicTypeRegistry().resolve( relationalJtd, jdbcType );
final TypeConfiguration typeConfiguration = getTypeConfiguration();
final JdbcType jdbcType = typeConfiguration.getJdbcTypeRegistry().getDescriptor( SqlTypes.SMALLINT );
final JavaType<Number> relationalJtd = typeConfiguration.getJavaTypeRegistry().getDescriptor( Integer.class );
return new ConvertedQueryLiteral(
sqmEnumLiteral.getEnumValue(),
new OrdinalEnumValueConverter<>( enumJtd, jdbcType, relationalJtd ),
jdbcMappingType
return new QueryLiteral<>(
sqmEnumLiteral.getEnumValue().ordinal(),
new CustomType<>(
new EnumType<>(
enumJtd.getJavaTypeClass(),
new OrdinalEnumValueConverter<>( enumJtd, jdbcType, relationalJtd ),
typeConfiguration
),
typeConfiguration
)
);
}

View File

@ -14,7 +14,9 @@ import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.query.BindableType;
import org.hibernate.query.SemanticException;
import org.hibernate.query.spi.QueryParameterBinding;
@ -30,6 +32,7 @@ import org.hibernate.sql.ast.tree.expression.SqlTupleContainer;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.basic.BasicResult;
import org.hibernate.type.descriptor.java.JavaType;
/**
* @author Steve Ebersole
@ -116,18 +119,30 @@ public class SqmParameterInterpretation implements Expression, DomainResultProdu
.getSessionFactory();
final SqmExpressible<?> sqmExpressible = nodeType.resolveExpressible( sessionFactory );
final JavaType<?> jdbcJavaType;
final BasicValueConverter<?, ?> converter;
if ( sqmExpressible instanceof JdbcMapping ) {
final JdbcMapping jdbcMapping = (JdbcMapping) sqmExpressible;
jdbcJavaType = jdbcMapping.getJdbcJavaType();
converter = jdbcMapping.getValueConverter();
}
else {
jdbcJavaType = sqmExpressible.getExpressibleJavaType();
converter = null;
}
final SqlSelection sqlSelection = creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
resolvedExpression,
sqmExpressible.getExpressibleJavaType(),
jdbcJavaType,
null,
sessionFactory.getTypeConfiguration()
);
return new BasicResult<>(
return new BasicResult(
sqlSelection.getValuesArrayPosition(),
resultVariable,
sqmExpressible.getExpressibleJavaType()
sqmExpressible.getExpressibleJavaType(),
converter
);
}
@ -161,10 +176,18 @@ public class SqmParameterInterpretation implements Expression, DomainResultProdu
.getSessionFactory();
final SqmExpressible<?> sqmExpressible = nodeType.resolveExpressible( sessionFactory );
final JavaType<?> jdbcJavaType;
if ( sqmExpressible instanceof JdbcMapping ) {
final JdbcMapping jdbcMapping = (JdbcMapping) sqmExpressible;
jdbcJavaType = jdbcMapping.getJdbcJavaType();
}
else {
jdbcJavaType = sqmExpressible.getExpressibleJavaType();
}
return creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
resolvedExpression,
sqmExpressible.getExpressibleJavaType(),
jdbcJavaType,
null,
sessionFactory.getTypeConfiguration()
);

View File

@ -7,7 +7,6 @@
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.BindableType;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.PathException;
import org.hibernate.query.SemanticException;
@ -25,7 +24,7 @@ import org.hibernate.type.descriptor.java.JavaType;
*/
public class SqmBasicValuedSimplePath<T>
extends AbstractSqmSimplePath<T>
implements BindableType<T>, SqmExpressible<T> {
implements SqmExpressible<T> {
public SqmBasicValuedSimplePath(
NavigablePath navigablePath,
SqmPathSource<T> referencedPathSource,

View File

@ -8,7 +8,6 @@ package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.BindableType;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.PathException;
import org.hibernate.query.hql.spi.SqmCreationState;
@ -24,7 +23,7 @@ import org.hibernate.type.descriptor.java.JavaType;
*/
public class SqmEmbeddedValuedSimplePath<T>
extends AbstractSqmSimplePath<T>
implements BindableType<T>, SqmExpressible<T> {
implements SqmExpressible<T> {
public SqmEmbeddedValuedSimplePath(
NavigablePath navigablePath,
SqmPathSource<T> referencedPathSource,

View File

@ -59,15 +59,15 @@ public class Conversion
public DomainResult createDomainResult(
String resultVariable,
DomainResultCreationState creationState) {
return new BasicResult(
return new BasicResult<>(
creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
this,
type.getJdbcMapping().getJavaTypeDescriptor(),
type.getJdbcMapping().getJdbcJavaType(),
null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()
).getValuesArrayPosition(),
resultVariable,
type.getJdbcMapping().getJavaTypeDescriptor()
type.getJdbcMapping()
);
}
@ -78,7 +78,7 @@ public class Conversion
sqlExpressionResolver.resolveSqlSelection(
this,
type.getJdbcMapping().getJavaTypeDescriptor(),
type.getJdbcMapping().getJdbcJavaType(),
null,
sqlAstCreationState.getCreationContext().getMappingMetamodel().getTypeConfiguration()
);

View File

@ -28,7 +28,7 @@ public class SqmLiteral<T> extends AbstractSqmExpression<T> {
public SqmLiteral(T value, SqmExpressible<? extends T> inherentType, NodeBuilder nodeBuilder) {
super( inherentType, nodeBuilder );
assert value != null;
assert value != null && ( inherentType == null || inherentType.getExpressibleJavaType().isInstance( value ) );
this.value = value;
}

View File

@ -23,6 +23,7 @@ public class ValueBindJpaCriteriaParameter<T> extends JpaCriteriaParameter<T>{
T value,
NodeBuilder nodeBuilder) {
super( null, type, false, nodeBuilder );
assert value == null || type == null || type.isInstance( value );
this.value = value;
}

View File

@ -3647,9 +3647,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
assert literal.getExpressionType().getJdbcTypeCount() == 1;
final JdbcMapping jdbcMapping = literal.getJdbcMapping();
final JdbcLiteralFormatter literalFormatter = jdbcMapping
.getJdbcType()
.getJdbcLiteralFormatter( jdbcMapping.getJavaTypeDescriptor() );
final JdbcLiteralFormatter literalFormatter = jdbcMapping.getJdbcLiteralFormatter();
// If we encounter a plain literal in the select clause which has no literal formatter, we must render it as parameter
if ( literalFormatter == null ) {
@ -4739,7 +4737,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
else {
assert jdbcParameter.getExpressionType().getJdbcTypeCount() == 1;
final JdbcMapping jdbcMapping = jdbcParameter.getExpressionType().getJdbcMappings().get( 0 );
final JdbcLiteralFormatter literalFormatter = jdbcMapping.getJdbcType().getJdbcLiteralFormatter( jdbcMapping.getJavaTypeDescriptor() );
final JdbcLiteralFormatter literalFormatter = jdbcMapping.getJdbcLiteralFormatter();
if ( literalFormatter == null ) {
throw new IllegalArgumentException( "Can't render parameter as literal, no literal formatter found" );
}

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.sql.ast.tree.expression;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
import org.hibernate.sql.ast.SqlAstWalker;
@ -48,16 +49,16 @@ public class Any implements Expression, DomainResultProducer {
public DomainResult createDomainResult(
String resultVariable,
DomainResultCreationState creationState) {
final JavaType javaType = type.getJdbcMappings().get( 0 ).getJavaTypeDescriptor();
return new BasicResult(
final JdbcMapping jdbcMapping = type.getJdbcMappings().get( 0 );
return new BasicResult<>(
creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
this,
javaType,
jdbcMapping.getJdbcJavaType(),
null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()
).getValuesArrayPosition(),
resultVariable,
javaType
jdbcMapping
);
}
@ -68,7 +69,7 @@ public class Any implements Expression, DomainResultProducer {
sqlExpressionResolver.resolveSqlSelection(
this,
type.getJdbcMappings().get( 0 ).getJavaTypeDescriptor(),
type.getJdbcMappings().get( 0 ).getJdbcJavaType(),
null,
sqlAstCreationState.getCreationContext().getMappingMetamodel().getTypeConfiguration()
);

View File

@ -57,7 +57,7 @@ public class BinaryArithmeticExpression implements Expression, DomainResultProdu
return new BasicResult(
sqlSelection.getValuesArrayPosition(),
resultVariable,
resultType.getJdbcMapping().getJavaTypeDescriptor()
resultType.getJdbcMapping()
);
}
@ -69,7 +69,7 @@ public class BinaryArithmeticExpression implements Expression, DomainResultProdu
public SqlSelection resolveSqlSelection(DomainResultCreationState creationState) {
return creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
this,
resultType.getJdbcMapping().getJavaTypeDescriptor(),
resultType.getJdbcMapping().getJdbcJavaType(),
null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()
);

View File

@ -67,7 +67,7 @@ public class CaseSearchedExpression implements Expression, DomainResultProducer
.getSqlExpressionResolver()
.resolveSqlSelection(
this,
type.getExpressibleJavaType(),
type.getJdbcMapping().getJdbcJavaType(),
null,
creationState.getSqlAstCreationState()
.getCreationContext()
@ -75,11 +75,10 @@ public class CaseSearchedExpression implements Expression, DomainResultProducer
.getTypeConfiguration()
);
//noinspection unchecked
return new BasicResult(
sqlSelection.getValuesArrayPosition(),
resultVariable,
type.getExpressibleJavaType()
type.getJdbcMapping()
);
}
@ -89,7 +88,7 @@ public class CaseSearchedExpression implements Expression, DomainResultProducer
.getSqlExpressionResolver();
sqlExpressionResolver.resolveSqlSelection(
this,
type.getExpressibleJavaType(),
type.getJdbcMapping().getJdbcJavaType(),
null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()
);

View File

@ -11,6 +11,7 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
import org.hibernate.sql.ast.SqlAstWalker;
@ -61,16 +62,16 @@ public class CaseSimpleExpression implements Expression, DomainResultProducer {
public DomainResult createDomainResult(
String resultVariable,
DomainResultCreationState creationState) {
final JavaType javaType = type.getJdbcMappings().get( 0 ).getJavaTypeDescriptor();
final JdbcMapping jdbcMapping = type.getJdbcMappings().get( 0 );
return new BasicResult(
creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
this,
javaType,
jdbcMapping.getJdbcJavaType(),
null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()
).getValuesArrayPosition(),
resultVariable,
javaType
jdbcMapping
);
}
@ -81,7 +82,7 @@ public class CaseSimpleExpression implements Expression, DomainResultProducer {
sqlExpressionResolver.resolveSqlSelection(
this,
type.getJdbcMappings().get( 0 ).getJavaTypeDescriptor(),
type.getJdbcMappings().get( 0 ).getJdbcJavaType(),
null,
sqlAstCreationState.getCreationContext().getMappingMetamodel().getTypeConfiguration()
);

View File

@ -9,6 +9,7 @@ package org.hibernate.sql.ast.tree.expression;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.hibernate.Remove;
import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
@ -33,7 +34,10 @@ import org.hibernate.type.descriptor.java.JavaType;
* but not a full ConvertibleModelPart.
*
* @author Steve Ebersole
* @deprecated remove
*/
@Remove
@Deprecated(forRemoval = true)
public class ConvertedQueryLiteral<D,R> implements Literal, DomainResultProducer<D> {
private final D domainLiteralValue;
private final R relationalLiteralValue;
@ -75,7 +79,7 @@ public class ConvertedQueryLiteral<D,R> implements Literal, DomainResultProducer
final SqlExpressionResolver expressionResolver = sqlAstCreationState.getSqlExpressionResolver();
expressionResolver.resolveSqlSelection(
this,
relationalMapping.getExpressibleJavaType(),
relationalMapping.getJdbcMapping().getJdbcJavaType(),
null,
sqlAstCreationState.getCreationContext().getMappingMetamodel().getTypeConfiguration()
);

View File

@ -57,15 +57,15 @@ public class Duration implements Expression, DomainResultProducer {
public DomainResult createDomainResult(
String resultVariable,
DomainResultCreationState creationState) {
return new BasicResult(
return new BasicResult<>(
creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
this,
type.getJdbcMapping().getJavaTypeDescriptor(),
type.getJdbcMapping().getJdbcJavaType(),
null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()
).getValuesArrayPosition(),
resultVariable,
type.getJdbcMapping().getJavaTypeDescriptor()
type.getJdbcMapping()
);
}
@ -76,7 +76,7 @@ public class Duration implements Expression, DomainResultProducer {
sqlExpressionResolver.resolveSqlSelection(
this,
type.getJdbcMapping().getJavaTypeDescriptor(),
type.getJdbcMapping().getJdbcJavaType(),
null,
sqlAstCreationState.getCreationContext().getMappingMetamodel().getTypeConfiguration()
);

View File

@ -104,7 +104,7 @@ public class EntityTypeLiteral implements Expression, MappingModelExpressible, D
createSqlSelection( creationState )
.getValuesArrayPosition(),
resultVariable,
discriminatorType.getExpressibleJavaType()
discriminatorType
);
}
@ -112,7 +112,7 @@ public class EntityTypeLiteral implements Expression, MappingModelExpressible, D
return creationState.getSqlAstCreationState().getSqlExpressionResolver()
.resolveSqlSelection(
this,
discriminatorType.getExpressibleJavaType(),
discriminatorType.getJdbcJavaType(),
null,
creationState.getSqlAstCreationState().getCreationContext()
.getMappingMetamodel().getTypeConfiguration()

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.sql.ast.tree.expression;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
import org.hibernate.sql.ast.SqlAstWalker;
@ -48,16 +49,16 @@ public class Every implements Expression, DomainResultProducer {
public DomainResult createDomainResult(
String resultVariable,
DomainResultCreationState creationState) {
final JavaType javaType = type.getJdbcMappings().get( 0 ).getJavaTypeDescriptor();
return new BasicResult(
final JdbcMapping jdbcMapping = type.getJdbcMappings().get( 0 );
return new BasicResult<>(
creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
this,
javaType,
jdbcMapping.getJdbcJavaType(),
null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()
).getValuesArrayPosition(),
resultVariable,
javaType
jdbcMapping
);
}
@ -68,7 +69,7 @@ public class Every implements Expression, DomainResultProducer {
sqlExpressionResolver.resolveSqlSelection(
this,
type.getJdbcMappings().get( 0 ).getJavaTypeDescriptor(),
type.getJdbcMappings().get( 0 ).getJdbcJavaType(),
null,
sqlAstCreationState.getCreationContext().getMappingMetamodel().getTypeConfiguration()
);

View File

@ -139,13 +139,12 @@ public class JdbcLiteral<T> implements Literal, MappingModelExpressible<T>, Doma
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
this,
jdbcMapping.getJavaTypeDescriptor(),
jdbcMapping.getJdbcJavaType(),
null,
sqlAstCreationState.getCreationContext().getMappingMetamodel().getTypeConfiguration()
);
//noinspection unchecked
return new BasicResult( sqlSelection.getValuesArrayPosition(), resultVariable, jdbcMapping.getJavaTypeDescriptor() );
return new BasicResult<>( sqlSelection.getValuesArrayPosition(), resultVariable, jdbcMapping );
}
@Override
@ -155,7 +154,7 @@ public class JdbcLiteral<T> implements Literal, MappingModelExpressible<T>, Doma
sqlExpressionResolver.resolveSqlSelection(
this,
jdbcMapping.getJavaTypeDescriptor(),
jdbcMapping.getJdbcJavaType(),
null,
sqlAstCreationState.getCreationContext().getMappingMetamodel().getTypeConfiguration()
);

View File

@ -121,10 +121,10 @@ public class Over<T> implements Expression, DomainResultProducer<T> {
@Override
public DomainResult<T> createDomainResult(String resultVariable, DomainResultCreationState creationState) {
final SqlSelection sqlSelection = createSelection( creationState.getSqlAstCreationState() );
return new BasicResult(
return new BasicResult<>(
sqlSelection.getValuesArrayPosition(),
resultVariable,
expression.getExpressionType().getJdbcMappings().get( 0 ).getMappedJavaType()
expression.getExpressionType().getJdbcMappings().get( 0 )
);
}
@ -136,7 +136,7 @@ public class Over<T> implements Expression, DomainResultProducer<T> {
private SqlSelection createSelection(SqlAstCreationState creationState) {
return creationState.getSqlExpressionResolver().resolveSqlSelection(
this,
expression.getExpressionType().getJdbcMappings().get( 0 ).getMappedJavaType(),
expression.getExpressionType().getJdbcMappings().get( 0 ).getJdbcJavaType(),
null,
creationState.getCreationContext().getSessionFactory().getTypeConfiguration()
);

View File

@ -8,15 +8,11 @@ package org.hibernate.sql.ast.tree.expression;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Locale;
import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.metamodel.mapping.ConvertibleModelPart;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.SqlTreeCreationException;
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.exec.spi.ExecutionContext;
@ -37,44 +33,9 @@ public class QueryLiteral<T> implements Literal, DomainResultProducer<T> {
private final BasicValuedMapping type;
public QueryLiteral(T value, BasicValuedMapping type) {
if ( type instanceof ConvertibleModelPart ) {
final ConvertibleModelPart convertibleModelPart = (ConvertibleModelPart) type;
final BasicValueConverter valueConverter = convertibleModelPart.getValueConverter();
if ( valueConverter != null ) {
final Object literalValue = value;
final Object sqlLiteralValue;
if ( literalValue == null || valueConverter.getDomainJavaType().getJavaTypeClass().isInstance(
literalValue ) ) {
sqlLiteralValue = valueConverter.toRelationalValue( literalValue );
}
else if ( valueConverter.getRelationalJavaType().getJavaTypeClass().isInstance( literalValue ) ) {
sqlLiteralValue = literalValue;
}
else {
throw new SqlTreeCreationException(
String.format(
Locale.ROOT,
"QueryLiteral type [`%s`] did not match domain Java-type [`%s`] nor JDBC Java-type [`%s`]",
literalValue.getClass(),
valueConverter.getDomainJavaType().getJavaTypeClass().getName(),
valueConverter.getRelationalJavaType().getJavaTypeClass().getName()
)
);
}
this.value = (T) sqlLiteralValue;
this.type = convertibleModelPart;
}
else {
this.value = value;
this.type = type;
}
}
else {
this.value = value;
this.type = type;
}
assert value == null || type.getJdbcMapping().getJdbcJavaType().isInstance( value );
this.value = value;
this.type = type;
}
@Override
@ -105,7 +66,7 @@ public class QueryLiteral<T> implements Literal, DomainResultProducer<T> {
.getSqlExpressionResolver();
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
this,
type.getMappedType().getMappedJavaType(),
type.getJdbcMapping().getJdbcJavaType(),
null,
creationState.getSqlAstCreationState()
.getCreationContext()
@ -113,10 +74,10 @@ public class QueryLiteral<T> implements Literal, DomainResultProducer<T> {
.getTypeConfiguration()
);
return new BasicResult(
return new BasicResult<>(
sqlSelection.getValuesArrayPosition(),
resultVariable,
type.getMappedType().getMappedJavaType()
type.getJdbcMapping()
);
}
@ -126,19 +87,10 @@ public class QueryLiteral<T> implements Literal, DomainResultProducer<T> {
int startPosition,
JdbcParameterBindings jdbcParameterBindings,
ExecutionContext executionContext) throws SQLException {
Object literalValue = getLiteralValue();
// Convert the literal value if needed to the JDBC type on demand to still serve the domain model type through getLiteralValue()
if ( type instanceof ConvertibleModelPart ) {
ConvertibleModelPart convertibleModelPart = (ConvertibleModelPart) type;
if ( convertibleModelPart.getValueConverter() != null ) {
//noinspection unchecked
literalValue = convertibleModelPart.getValueConverter().toRelationalValue( literalValue );
}
}
//noinspection unchecked
type.getJdbcMapping().getJdbcValueBinder().bind(
statement,
literalValue,
getLiteralValue(),
startPosition,
executionContext.getSession()
);
@ -148,7 +100,7 @@ public class QueryLiteral<T> implements Literal, DomainResultProducer<T> {
public void applySqlSelections(DomainResultCreationState creationState) {
creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
this,
type.getJdbcMapping().getJavaTypeDescriptor(),
type.getJdbcMapping().getJdbcJavaType(),
null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()
);

View File

@ -69,9 +69,10 @@ public class SqlTuple implements Expression, SqlTupleContainer, DomainResultProd
final JavaType javaType = ( (SqmExpressible<?>) valueMapping ).getExpressibleJavaType();
final int[] valuesArrayPositions = new int[expressions.size()];
for ( int i = 0; i < expressions.size(); i++ ) {
final Expression expression = expressions.get( i );
valuesArrayPositions[i] = creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
expressions.get( i ),
javaType,
expression,
expression.getExpressionType().getJdbcMappings().get( 0 ).getJdbcJavaType(),
null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()
).getValuesArrayPosition();

View File

@ -59,16 +59,15 @@ public class UnaryOperation implements Expression, DomainResultProducer {
DomainResultCreationState creationState) {
final SqlSelection sqlSelection = creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
this,
type.getJdbcMapping().getJavaTypeDescriptor(),
type.getJdbcMapping().getJdbcJavaType(),
null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()
);
//noinspection unchecked
return new BasicResult(
return new BasicResult<>(
sqlSelection.getValuesArrayPosition(),
resultVariable,
type.getJdbcMapping().getJavaTypeDescriptor()
type.getJdbcMapping()
);
}
@ -79,7 +78,7 @@ public class UnaryOperation implements Expression, DomainResultProducer {
sqlExpressionResolver.resolveSqlSelection(
this,
type.getJdbcMapping().getJavaTypeDescriptor(),
type.getJdbcMapping().getJdbcJavaType(),
null,
sqlAstCreationState.getCreationContext().getMappingMetamodel().getTypeConfiguration()
);

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.sql.ast.tree.predicate;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.sql.ast.spi.SqlAstTreeHelper;
@ -36,16 +37,15 @@ public interface Predicate extends Expression, DomainResultProducer<Boolean> {
default DomainResult<Boolean> createDomainResult(String resultVariable, DomainResultCreationState creationState) {
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
final JavaType javaType = getExpressionType().getJdbcMappings().get( 0 ).getJavaTypeDescriptor();
final JdbcMapping jdbcMapping = getExpressionType().getJdbcMappings().get( 0 );
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
this,
javaType,
jdbcMapping.getJdbcJavaType(),
null,
sqlAstCreationState.getCreationContext().getMappingMetamodel().getTypeConfiguration()
);
//noinspection unchecked
return new BasicResult( sqlSelection.getValuesArrayPosition(), resultVariable, javaType );
return new BasicResult<>( sqlSelection.getValuesArrayPosition(), resultVariable, jdbcMapping );
}
@Override
@ -55,7 +55,7 @@ public interface Predicate extends Expression, DomainResultProducer<Boolean> {
sqlExpressionResolver.resolveSqlSelection(
this,
getExpressionType().getJdbcMappings().get( 0 ).getJavaTypeDescriptor(),
getExpressionType().getJdbcMappings().get( 0 ).getJdbcJavaType(),
null,
sqlAstCreationState.getCreationContext().getMappingMetamodel().getTypeConfiguration()
);

Some files were not shown because too many files have changed in this diff Show More