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.mapping.internal.BasicAttributeMapping;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister; 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.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory; 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.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.isOneOf; import static org.hamcrest.Matchers.isOneOf;
/** /**
@ -60,32 +62,35 @@ public class BooleanMappingTests {
{ {
final BasicAttributeMapping convertedYesNo = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("convertedYesNo"); final BasicAttributeMapping convertedYesNo = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("convertedYesNo");
final JdbcMapping jdbcMapping = convertedYesNo.getJdbcMapping(); 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( assertThat(
jdbcMapping.getJdbcType().getJdbcTypeCode(), jdbcMapping.getJdbcType().getJdbcTypeCode(),
// could be NCHAR if nationalization is globally enabled // 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 BasicAttributeMapping convertedTrueFalse = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("convertedTrueFalse");
final JdbcMapping jdbcMapping = convertedTrueFalse.getJdbcMapping(); 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( assertThat(
jdbcMapping.getJdbcType().getJdbcTypeCode(), jdbcMapping.getJdbcType().getJdbcTypeCode(),
// could be NCHAR if nationalization is globally enabled // 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 BasicAttributeMapping convertedNumeric = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("convertedNumeric");
final JdbcMapping jdbcMapping = convertedNumeric.getJdbcMapping(); 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( assertThat(
jdbcMapping.getJdbcType().getJdbcTypeCode(), 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.annotations.Immutable;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping; 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.model.convert.spi.JpaAttributeConverter;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan; import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
import org.hibernate.type.descriptor.java.MutabilityPlan; 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.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactory;
@ -46,18 +49,25 @@ public class BitSetConverterImmutableTests {
@Test @Test
public void verifyMappings(SessionFactoryScope scope) { public void verifyMappings(SessionFactoryScope scope) {
final SessionFactoryImplementor sessionFactory = scope.getSessionFactory(); final SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
final MappingMetamodelImplementor mappingMetamodel = scope.getSessionFactory() final MappingMetamodelImplementor mappingMetamodel = sessionFactory.getRuntimeMetamodels()
.getRuntimeMetamodels()
.getMappingMetamodel(); .getMappingMetamodel();
final EntityPersister entityDescriptor = mappingMetamodel.findEntityDescriptor(Product.class); final EntityPersister entityDescriptor = mappingMetamodel.findEntityDescriptor(Product.class);
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("bitSet"); 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)); assertThat( jdbcMapping, instanceOf( ConvertedBasicTypeImpl.class ) );
final JpaAttributeConverter converter = (JpaAttributeConverter) attributeMapping.getValueConverter(); final BasicValueConverter<?, ?> converter = jdbcMapping.getValueConverter();
assertThat(converter.getConverterBean().getBeanClass(), equalTo(BitSetConverter.class)); assertThat(
converter,
instanceOf( JpaAttributeConverter.class )
);
assertThat(
( (JpaAttributeConverter<?, ?>) converter ).getConverterBean().getBeanClass(),
equalTo( BitSetConverter.class )
);
Assertions.assertThat(attributeMapping.getExposedMutabilityPlan()).isNotInstanceOf(BitSetMutabilityPlan.class); Assertions.assertThat(attributeMapping.getExposedMutabilityPlan()).isNotInstanceOf(BitSetMutabilityPlan.class);
Assertions.assertThat(attributeMapping.getExposedMutabilityPlan()).isInstanceOf(ImmutableMutabilityPlan.class); Assertions.assertThat(attributeMapping.getExposedMutabilityPlan()).isInstanceOf(ImmutableMutabilityPlan.class);
@ -67,11 +77,11 @@ public class BitSetConverterImmutableTests {
Assertions.assertThat(((MutabilityPlan) attributeMapping.getExposedMutabilityPlan()).deepCopy(sample)).isSameAs(sample); Assertions.assertThat(((MutabilityPlan) attributeMapping.getExposedMutabilityPlan()).deepCopy(sample)).isSameAs(sample);
assertThat( assertThat(
attributeMapping.getJdbcMapping().getJdbcType().getJdbcTypeCode(), jdbcMapping.getJdbcType().getJdbcTypeCode(),
isOneOf(Types.VARCHAR, Types.NVARCHAR) isOneOf(Types.VARCHAR, Types.NVARCHAR)
); );
assertThat(attributeMapping.getJdbcMapping().getJavaTypeDescriptor().getJavaTypeClass(), equalTo(String.class)); assertThat(converter.getRelationalJavaType().getJavaTypeClass(), equalTo(String.class));
} }
@Table(name = "products") @Table(name = "products")

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -47,7 +47,7 @@ public class BitSetJdbcTypeTests {
assertThat( attributeMapping.getJavaType().getJavaTypeClass(), equalTo( BitSet.class)); assertThat( attributeMapping.getJavaType().getJavaTypeClass(), equalTo( BitSet.class));
assertThat(attributeMapping.getValueConverter(), nullValue()); assertThat(attributeMapping.getJdbcMapping().getValueConverter(), nullValue());
assertThat( assertThat(
attributeMapping.getJdbcMapping().getJdbcType().getJdbcTypeCode(), 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> { public class ConvertedBasicTypeResolution<J> implements BasicValue.Resolution<J> {
private final ConvertedBasicType basicType; private final ConvertedBasicType basicType;
private final ValueConverterTypeAdapter adapted; // private final ValueConverterTypeAdapter adapted;
public ConvertedBasicTypeResolution( public ConvertedBasicTypeResolution(
ConvertedBasicType basicType, ConvertedBasicType basicType,
@ -30,21 +30,21 @@ public class ConvertedBasicTypeResolution<J> implements BasicValue.Resolution<J>
final BasicValueConverter valueConverter = basicType.getValueConverter(); final BasicValueConverter valueConverter = basicType.getValueConverter();
this.adapted = new ValueConverterTypeAdapter( // this.adapted = new ValueConverterTypeAdapter(
valueConverter.getClass().getTypeName(), // valueConverter.getClass().getTypeName(),
valueConverter, // valueConverter,
stdIndicators // stdIndicators
); // );
} }
@Override @Override
public BasicType<J> getLegacyResolvedBasicType() { public BasicType<J> getLegacyResolvedBasicType() {
return adapted; return basicType;
} }
@Override @Override
public JdbcMapping getJdbcMapping() { public JdbcMapping getJdbcMapping() {
return adapted; return basicType;
} }
@Override @Override
@ -59,7 +59,7 @@ public class ConvertedBasicTypeResolution<J> implements BasicValue.Resolution<J>
@Override @Override
public JdbcType getJdbcType() { public JdbcType getJdbcType() {
return adapted.getJdbcType(); return basicType.getJdbcType();
} }
@Override @Override

View File

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

View File

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

View File

@ -7,12 +7,10 @@
package org.hibernate.boot.model.process.internal; package org.hibernate.boot.model.process.internal;
import java.util.function.Function; import java.util.function.Function;
import jakarta.persistence.AttributeConverter;
import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor; import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor;
import org.hibernate.boot.model.convert.spi.ConverterDescriptor; import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
import org.hibernate.boot.model.convert.spi.JpaAttributeConverterCreationContext; 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.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.spi.MetadataBuildingContext; import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.mapping.BasicValue; 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.metamodel.model.convert.spi.JpaAttributeConverter;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.converter.AttributeConverterMutabilityPlanImpl; 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.BasicJavaType;
import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan; import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.MutabilityPlan; import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators; import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.internal.CustomMutabilityConvertedBasicTypeImpl;
import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfiguration;
/** /**
@ -174,45 +172,7 @@ public class NamedConverterResolution<J> implements BasicValue.Resolution<J> {
assert mutabilityPlan != null; assert mutabilityPlan != null;
this.mutabilityPlan = mutabilityPlan; this.mutabilityPlan = mutabilityPlan;
this.jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve( this.legacyResolvedType = new CustomMutabilityConvertedBasicTypeImpl<>(
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<>(
ConverterDescriptor.TYPE_NAME_PREFIX ConverterDescriptor.TYPE_NAME_PREFIX
+ valueConverter.getConverterJavaType().getJavaType().getTypeName(), + valueConverter.getConverterJavaType().getJavaType().getTypeName(),
String.format( String.format(
@ -220,12 +180,11 @@ public class NamedConverterResolution<J> implements BasicValue.Resolution<J> {
domainJtd.getJavaType().getTypeName(), domainJtd.getJavaType().getTypeName(),
relationalJtd.getJavaType().getTypeName() relationalJtd.getJavaType().getTypeName()
), ),
valueConverter,
jdbcType, jdbcType,
relationalJtd, valueConverter,
domainJtd,
mutabilityPlan mutabilityPlan
); );
this.jdbcMapping = legacyResolvedType;
} }
@Override @Override

View File

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

View File

@ -11,6 +11,7 @@ import java.lang.annotation.Repeatable;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member; import java.lang.reflect.Member;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; 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.annotations.common.reflection.XProperty;
import org.hibernate.boot.model.IdGeneratorStrategyInterpreter; import org.hibernate.boot.model.IdGeneratorStrategyInterpreter;
import org.hibernate.boot.model.IdentifierGeneratorDefinition; 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.model.convert.spi.RegisteredConversion;
import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; 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.PropertyBinder;
import org.hibernate.cfg.annotations.QueryBinder; import org.hibernate.cfg.annotations.QueryBinder;
import org.hibernate.cfg.annotations.TableBinder; import org.hibernate.cfg.annotations.TableBinder;
import org.hibernate.cfg.internal.ConvertedJdbcMapping;
import org.hibernate.cfg.internal.NullableDiscriminatorColumnSecondPass; import org.hibernate.cfg.internal.NullableDiscriminatorColumnSecondPass;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.engine.OptimisticLockStyle; import org.hibernate.engine.OptimisticLockStyle;
@ -125,6 +126,7 @@ import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.factory.spi.CustomIdGeneratorCreationContext; import org.hibernate.id.factory.spi.CustomIdGeneratorCreationContext;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.GenericsHelper;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.jpa.event.internal.CallbackDefinitionResolverLegacyImpl; import org.hibernate.jpa.event.internal.CallbackDefinitionResolverLegacyImpl;
import org.hibernate.jpa.event.spi.CallbackType; 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.ToOne;
import org.hibernate.mapping.UnionSubclass; import org.hibernate.mapping.UnionSubclass;
import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.model.convert.internal.JpaAttributeConverterImpl;
import org.hibernate.metamodel.spi.EmbeddableInstantiator; import org.hibernate.metamodel.spi.EmbeddableInstantiator;
import org.hibernate.property.access.internal.PropertyAccessStrategyCompositeUserTypeImpl; import org.hibernate.property.access.internal.PropertyAccessStrategyCompositeUserTypeImpl;
import org.hibernate.property.access.internal.PropertyAccessStrategyMixedImpl; 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.java.spi.JavaTypeRegistry;
import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators; import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.CompositeUserType; import org.hibernate.usertype.CompositeUserType;
import org.hibernate.usertype.UserType; import org.hibernate.usertype.UserType;
@ -1756,7 +1760,35 @@ public final class AnnotationBinder {
final ManagedBeanRegistry beanRegistry = serviceRegistry.getService( ManagedBeanRegistry.class ); final ManagedBeanRegistry beanRegistry = serviceRegistry.getService( ManagedBeanRegistry.class );
final ManagedBean<AttributeConverter<?, ?>> bean = beanRegistry.getBean( type ); 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) { 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 java.lang.reflect.ParameterizedType;
import org.hibernate.Remove;
import org.hibernate.internal.util.GenericsHelper; import org.hibernate.internal.util.GenericsHelper;
import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.model.convert.internal.JpaAttributeConverterImpl; import org.hibernate.metamodel.model.convert.internal.JpaAttributeConverterImpl;
import org.hibernate.resource.beans.spi.ManagedBean; import org.hibernate.resource.beans.spi.ManagedBean;
import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor; 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.JavaType;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry; import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.descriptor.jdbc.JdbcType; 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 * Ad-hoc JdbcMapping implementation for cases where we only have a converter
* *
* @author Steve Ebersole * @author Steve Ebersole
* @deprecated remove
*/ */
@Remove
@Deprecated(forRemoval = true)
public class ConvertedJdbcMapping<T> implements JdbcMapping { public class ConvertedJdbcMapping<T> implements JdbcMapping {
private final JavaType<T> domainJtd; private final JavaType<T> domainJtd;
@ -55,11 +58,12 @@ public class ConvertedJdbcMapping<T> implements JdbcMapping {
relationalJtd relationalJtd
); );
this.jdbcType = new AttributeConverterJdbcTypeAdapter( this.jdbcType = null;
converterDescriptor, // new AttributeConverterJdbcTypeAdapter(
relationalJtd.getRecommendedJdbcType( typeConfiguration.getCurrentBaseSqlTypeIndicators() ), // converterDescriptor,
relationalJtd // relationalJtd.getRecommendedJdbcType( typeConfiguration.getCurrentBaseSqlTypeIndicators() ),
); // relationalJtd
// );
} }
@Override @Override
@ -72,6 +76,11 @@ public class ConvertedJdbcMapping<T> implements JdbcMapping {
return jdbcType; return jdbcType;
} }
@Override
public JavaType<?> getJdbcJavaType() {
return relationalJtd;
}
@Override @Override
public ValueExtractor<?> getJdbcValueExtractor() { public ValueExtractor<?> getJdbcValueExtractor() {
return jdbcType.getExtractor( domainJtd ); return jdbcType.getExtractor( domainJtd );

View File

@ -9,11 +9,13 @@ package org.hibernate.internal;
import java.util.Objects; import java.util.Objects;
import org.hibernate.metamodel.mapping.JdbcMapping; 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.ast.tree.expression.JdbcParameter;
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl; import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
import org.hibernate.sql.exec.internal.JdbcParameterImpl; import org.hibernate.sql.exec.internal.JdbcParameterImpl;
import org.hibernate.sql.exec.spi.JdbcParameterBinder; import org.hibernate.sql.exec.spi.JdbcParameterBinder;
import org.hibernate.sql.exec.spi.JdbcParameterBinding; import org.hibernate.sql.exec.spi.JdbcParameterBinding;
import org.hibernate.type.descriptor.java.JavaType;
/** /**
* @author Nathan Xu * @author Nathan Xu
@ -38,7 +40,11 @@ public class FilterJdbcParameter {
} }
public JdbcParameterBinding getBinding() { 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 @Override
@ -52,11 +58,18 @@ public class FilterJdbcParameter {
FilterJdbcParameter that = (FilterJdbcParameter) o; FilterJdbcParameter that = (FilterJdbcParameter) o;
return Objects.equals( parameter, that.parameter ) && return Objects.equals( parameter, that.parameter ) &&
Objects.equals( jdbcMapping, that.jdbcMapping ) && Objects.equals( jdbcMapping, that.jdbcMapping ) &&
Objects.equals( jdbcParameterValue, that.jdbcParameterValue ); ( (JavaType<Object>) jdbcMapping.getMappedJavaType() ).areEqual(
jdbcParameterValue,
that.jdbcParameterValue
);
} }
@Override @Override
public int hashCode() { 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.internal.ClassBasedConverterDescriptor;
import org.hibernate.boot.model.convert.spi.ConverterDescriptor; import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
import org.hibernate.boot.model.convert.spi.JpaAttributeConverterCreationContext; 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.InferredBasicValueResolver;
import org.hibernate.boot.model.process.internal.NamedBasicTypeResolution; import org.hibernate.boot.model.process.internal.NamedBasicTypeResolution;
import org.hibernate.boot.model.process.internal.NamedConverterResolution; 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.ManagedBean;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry; import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
import org.hibernate.type.ConvertedBasicType;
import org.hibernate.type.CustomType; import org.hibernate.type.CustomType;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.BasicJavaType; 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.JavaType;
import org.hibernate.type.descriptor.java.MutabilityPlan; import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.jdbc.JdbcType; 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; JavaType<?> jtd = null;
// determine JavaType if we can // 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; final JdbcType jdbcType;
if ( explicitJdbcTypeAccess != null ) { if ( explicitJdbcTypeAccess != null ) {
jdbcType = explicitJdbcTypeAccess.apply( typeConfiguration ); jdbcType = explicitJdbcTypeAccess.apply( typeConfiguration );
@ -587,16 +623,8 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
valueConverter = converterDescriptor.createJpaAttributeConverter( converterCreationContext ); valueConverter = converterDescriptor.createJpaAttributeConverter( converterCreationContext );
domainJtd = valueConverter.getDomainJavaType(); 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 { else {
valueConverter = null; valueConverter = basicTypeByName.getValueConverter();
domainJtd = basicTypeByName.getJavaTypeDescriptor(); domainJtd = basicTypeByName.getJavaTypeDescriptor();
} }

View File

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

View File

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

View File

@ -17,5 +17,7 @@ public interface ConvertibleModelPart extends BasicValuedModelPart {
/** /**
* Get the value converter applied to this model part if any * 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.Collections;
import java.util.List; import java.util.List;
import org.hibernate.Incubating;
import org.hibernate.mapping.IndexedConsumer; import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.query.sqm.CastType; import org.hibernate.query.sqm.CastType;
import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor; import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.descriptor.jdbc.JdbcType;
/** /**
@ -50,11 +53,34 @@ public interface JdbcMapping extends MappingType, JdbcMappingContainer {
*/ */
ValueBinder getJdbcValueBinder(); ValueBinder getJdbcValueBinder();
/**
* The strategy for formatting values of this expressible type to
* a SQL literal.
*/
@Incubating
default JdbcLiteralFormatter getJdbcLiteralFormatter() {
return getJdbcType().getJdbcLiteralFormatter( getMappedJavaType() );
}
@Override @Override
default JavaType<?> getMappedJavaType() { default JavaType<?> getMappedJavaType() {
return getJavaTypeDescriptor(); 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 @Override
default int getJdbcTypeCount() { default int getJdbcTypeCount() {
return 1; return 1;

View File

@ -7,9 +7,7 @@
package org.hibernate.metamodel.mapping.internal; package org.hibernate.metamodel.mapping.internal;
import java.util.function.BiConsumer; 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.FetchTiming;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; 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.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingType; import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.metamodel.mapping.SelectableConsumer; import org.hibernate.metamodel.mapping.SelectableConsumer;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.metamodel.model.domain.NavigableRole; import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.persister.entity.DiscriminatorType; import org.hibernate.persister.entity.DiscriminatorType;
import org.hibernate.persister.entity.EntityPersister; 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.sql.results.graph.basic.BasicResult;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.JavaType; 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()` * @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 { public abstract class AbstractDiscriminatorMapping implements EntityDiscriminatorMapping {
private final NavigableRole role; private final NavigableRole role;
private final JdbcMapping jdbcMapping;
private final EntityPersister entityDescriptor; private final EntityPersister entityDescriptor;
private final DiscriminatorType<?> discriminatorType; private final DiscriminatorType<?> discriminatorType;
private final SessionFactoryImplementor sessionFactory; private final SessionFactoryImplementor sessionFactory;
private final DomainResultConverter<?> domainResultConverter;
public AbstractDiscriminatorMapping( public AbstractDiscriminatorMapping(
JdbcMapping jdbcMapping,
EntityPersister entityDescriptor, EntityPersister entityDescriptor,
DiscriminatorType<?> discriminatorType, DiscriminatorType<?> discriminatorType,
MappingModelCreationProcess creationProcess) { MappingModelCreationProcess creationProcess) {
this.jdbcMapping = jdbcMapping;
this.entityDescriptor = entityDescriptor; this.entityDescriptor = entityDescriptor;
this.discriminatorType = discriminatorType; this.discriminatorType = discriminatorType;
role = entityDescriptor.getNavigableRole().append( EntityDiscriminatorMapping.ROLE_NAME ); role = entityDescriptor.getNavigableRole().append( EntityDiscriminatorMapping.ROLE_NAME );
sessionFactory = creationProcess.getCreationContext().getSessionFactory(); sessionFactory = creationProcess.getCreationContext().getSessionFactory();
domainResultConverter = DomainResultConverter.create(
entityDescriptor,
this::getConcreteEntityNameForDiscriminatorValue,
discriminatorType.getUnderlyingType(),
sessionFactory
);
} }
public EntityPersister getEntityDescriptor() { public EntityPersister getEntityDescriptor() {
@ -101,7 +81,7 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
@Override @Override
public JdbcMapping getJdbcMapping() { public JdbcMapping getJdbcMapping() {
return jdbcMapping; return discriminatorType;
} }
@Override @Override
@ -138,12 +118,10 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
creationState.getSqlAstCreationState() creationState.getSqlAstCreationState()
); );
//noinspection unchecked return new BasicResult<>(
return new BasicResult(
sqlSelection.getValuesArrayPosition(), sqlSelection.getValuesArrayPosition(),
resultVariable, resultVariable,
domainResultConverter.getDomainJavaType(), discriminatorType,
domainResultConverter,
navigablePath navigablePath
); );
} }
@ -157,7 +135,7 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
final SqlExpressionResolver expressionResolver = creationState.getSqlExpressionResolver(); final SqlExpressionResolver expressionResolver = creationState.getSqlExpressionResolver();
return expressionResolver.resolveSqlSelection( return expressionResolver.resolveSqlSelection(
resolveSqlExpression( navigablePath, jdbcMappingToUse, tableGroup, creationState ), resolveSqlExpression( navigablePath, jdbcMappingToUse, tableGroup, creationState ),
jdbcMappingToUse.getJavaTypeDescriptor(), jdbcMappingToUse.getJdbcJavaType(),
fetchParent, fetchParent,
creationState.getCreationContext().getSessionFactory().getTypeConfiguration() creationState.getCreationContext().getSessionFactory().getTypeConfiguration()
); );
@ -191,7 +169,6 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
fetchParent, fetchParent,
fetchablePath, fetchablePath,
this, this,
null,
fetchTiming, fetchTiming,
creationState creationState
); );
@ -224,7 +201,7 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
int offset, int offset,
JdbcValuesConsumer valuesConsumer, JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
valuesConsumer.consume( offset, convertToRelational( value ), getJdbcMapping() ); valuesConsumer.consume( offset, value, getJdbcMapping() );
return getJdbcTypeCount(); return getJdbcTypeCount();
} }
@ -236,175 +213,18 @@ public abstract class AbstractDiscriminatorMapping implements EntityDiscriminato
@Override @Override
public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) { public void breakDownJdbcValues(Object domainValue, JdbcValueConsumer valueConsumer, SharedSessionContractImplementor session) {
valueConsumer.consume( convertToRelational( domainValue ), this ); valueConsumer.consume( disassemble( domainValue, session ), this );
}
private Object convertToRelational(Object domainValue) {
if ( domainResultConverter != null ) {
return domainResultConverter.toRelationalValue( domainValue );
}
return domainValue;
} }
@Override @Override
public Object disassemble(Object value, SharedSessionContractImplementor session) { public Object disassemble(Object value, SharedSessionContractImplementor session) {
return convertToRelational( value ); return 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 );
} }
@Override @Override
public int forEachSelectable(int offset, SelectableConsumer consumer) { public int forEachSelectable(int offset, SelectableConsumer consumer) {
return EntityDiscriminatorMapping.super.forEachSelectable( offset, consumer ); consumer.accept( offset, this );
} return getJdbcTypeCount();
@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;
}
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,5 +20,5 @@ import jakarta.persistence.metamodel.EmbeddableType;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface EmbeddableDomainType<J> 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; 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.metamodel.model.domain.SimpleDomainType;
import org.hibernate.query.BindableType;
import org.hibernate.query.ReturnableType; import org.hibernate.query.ReturnableType;
import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmPath;
@ -21,7 +17,7 @@ import org.hibernate.spi.NavigablePath;
* *
*/ */
public class AnyDiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D> public class AnyDiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
implements BindableType<D>, ReturnableType<D> { implements ReturnableType<D> {
public AnyDiscriminatorSqmPathSource( public AnyDiscriminatorSqmPathSource(

View File

@ -6,7 +6,6 @@
*/ */
package org.hibernate.metamodel.model.domain.internal; package org.hibernate.metamodel.model.domain.internal;
import org.hibernate.query.BindableType;
import org.hibernate.metamodel.UnsupportedMappingException; import org.hibernate.metamodel.UnsupportedMappingException;
import org.hibernate.metamodel.model.domain.AnyMappingDomainType; import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
import org.hibernate.metamodel.model.domain.BasicDomainType; import org.hibernate.metamodel.model.domain.BasicDomainType;
@ -20,7 +19,7 @@ import static jakarta.persistence.metamodel.Bindable.BindableType.SINGULAR_ATTRI
/** /**
* @author Steve Ebersole * @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 SqmPathSource<?> keyPathSource;
private final AnyDiscriminatorSqmPathSource discriminatorPathSource; 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.metamodel.mapping.MappingModelExpressible;
import org.hibernate.query.ReturnableType; import org.hibernate.query.ReturnableType;
import org.hibernate.metamodel.model.domain.TupleType; import org.hibernate.metamodel.model.domain.TupleType;
import org.hibernate.query.BindableType;
import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.SqmExpressible;
import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.Clause;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
@ -27,7 +26,6 @@ import org.hibernate.type.descriptor.java.ObjectArrayJavaType;
* @author Christian Beikov * @author Christian Beikov
*/ */
public class ArrayTupleType implements TupleType<Object[]>, public class ArrayTupleType implements TupleType<Object[]>,
BindableType<Object[]>,
ReturnableType<Object[]>, ReturnableType<Object[]>,
MappingModelExpressible<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.metamodel.model.domain.BasicDomainType;
import org.hibernate.query.ReturnableType; import org.hibernate.query.ReturnableType;
import org.hibernate.query.BindableType;
import org.hibernate.spi.NavigablePath; import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath; import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
@ -19,7 +18,7 @@ import org.hibernate.query.sqm.tree.domain.SqmPath;
*/ */
public class BasicSqmPathSource<J> public class BasicSqmPathSource<J>
extends AbstractSqmPathSource<J> extends AbstractSqmPathSource<J>
implements BindableType<J>, ReturnableType<J> { implements ReturnableType<J> {
public BasicSqmPathSource( public BasicSqmPathSource(
String localPathName, 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.DomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.ReturnableType; import org.hibernate.query.ReturnableType;
import org.hibernate.query.BindableType;
import org.hibernate.spi.NavigablePath; import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmPath;
@ -22,7 +21,7 @@ import org.hibernate.query.sqm.tree.domain.SqmPath;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class DiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D> public class DiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
implements BindableType<D>, ReturnableType<D> { implements ReturnableType<D> {
private final EntityDomainType<?> entityDomainType; private final EntityDomainType<?> entityDomainType;
private final EntityMappingType entityMapping; 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.AbstractManagedType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType; import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel; import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.query.BindableType;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
/** /**
@ -25,7 +24,7 @@ import org.hibernate.type.descriptor.java.JavaType;
*/ */
public class EmbeddableTypeImpl<J> public class EmbeddableTypeImpl<J>
extends AbstractManagedType<J> extends AbstractManagedType<J>
implements EmbeddableDomainType<J>, BindableType<J>, Serializable { implements EmbeddableDomainType<J>, Serializable {
private final boolean isDynamic; private final boolean isDynamic;

View File

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

View File

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

View File

@ -282,6 +282,13 @@ public class MappingMetamodelImpl implements MappingMetamodelImplementor, Metamo
modelCreationContext modelCreationContext
); );
entityPersisterMap.put( model.getEntityName(), cp ); 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 if ( cp.getConcreteProxyClass() != null
&& cp.getConcreteProxyClass().isInterface() && cp.getConcreteProxyClass().isInterface()

View File

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

View File

@ -2381,7 +2381,10 @@ public abstract class AbstractEntityPersister
} }
private DiscriminatorMetadata buildTypeDiscriminatorMetadata() { 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) { public static String generateTableAlias(String rootAlias, int tableNumber) {

View File

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

View File

@ -8,7 +8,6 @@ package org.hibernate.persister.entity;
import java.sql.CallableStatement; import java.sql.CallableStatement;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -20,15 +19,16 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.metamodel.RepresentationMode; 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.AbstractType;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor; 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.ClassJavaType;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.StringJavaType; import org.hibernate.type.descriptor.java.StringJavaType;
import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter;
import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.descriptor.jdbc.JdbcType;
/** /**
@ -36,7 +36,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcType;
* *
* @author Steve Ebersole * @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 BasicType<Object> underlyingType;
private final Loadable persister; private final Loadable persister;
@ -50,8 +50,60 @@ public class DiscriminatorType<T> extends AbstractType implements BasicType<T>,
} }
@Override @Override
public JdbcMapping getJdbcMapping() { public BasicValueConverter<T, ?> getValueConverter() {
return getUnderlyingType().getJdbcMapping(); 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 @Override
@ -78,43 +130,14 @@ public class DiscriminatorType<T> extends AbstractType implements BasicType<T>,
public T extract(CallableStatement statement, int paramIndex, SharedSessionContractImplementor session) public T extract(CallableStatement statement, int paramIndex, SharedSessionContractImplementor session)
throws SQLException { throws SQLException {
final Object discriminatorValue = underlyingType.extract( statement, paramIndex, session ); final Object discriminatorValue = underlyingType.extract( statement, paramIndex, session );
return (T) get( discriminatorValue, session ); return toDomainValue( discriminatorValue );
} }
@Override @Override
public T extract(CallableStatement statement, String paramName, SharedSessionContractImplementor session) public T extract(CallableStatement statement, String paramName, SharedSessionContractImplementor session)
throws SQLException { throws SQLException {
final Object discriminatorValue = underlyingType.extract( statement, paramName, session ); final Object discriminatorValue = underlyingType.extract( statement, paramName, session );
return (T) get( discriminatorValue, session ); return toDomainValue( discriminatorValue );
}
@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;
} }
@Override @Override
@ -133,31 +156,7 @@ public class DiscriminatorType<T> extends AbstractType implements BasicType<T>,
Object value, Object value,
int index, int index,
SharedSessionContractImplementor session) throws HibernateException, SQLException { SharedSessionContractImplementor session) throws HibernateException, SQLException {
final Loadable loadable = (Loadable) session.getFactory() underlyingType.nullSafeSet( st, toRelationalValue( (T) value ), index, session);
.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 );
} }
@Override @Override
@ -190,6 +189,10 @@ public class DiscriminatorType<T> extends AbstractType implements BasicType<T>,
return Objects.equals( old, current ); return Objects.equals( old, current );
} }
@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
return toRelationalValue( (T) value );
}
// simple delegation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // simple delegation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -233,12 +236,17 @@ public class DiscriminatorType<T> extends AbstractType implements BasicType<T>,
@Override @Override
public ValueExtractor<T> getJdbcValueExtractor() { public ValueExtractor<T> getJdbcValueExtractor() {
return this; return (ValueExtractor<T>) underlyingType.getJdbcValueExtractor();
} }
@Override @Override
public ValueBinder<T> getJdbcValueBinder() { public ValueBinder<T> getJdbcValueBinder() {
return this; return (ValueBinder<T>) underlyingType.getJdbcValueBinder();
}
@Override
public JdbcLiteralFormatter getJdbcLiteralFormatter() {
return underlyingType.getJdbcLiteralFormatter();
} }
@Override @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( final Expression sqlExpression = sqlExpressionResolver.resolveSqlExpression(
columnReferenceKey, columnReferenceKey,
sqlAstProcessingState -> new ColumnReference( 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." ); 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( jdbcParameterBindings.addBinding(
(JdbcParameter) registration.getParameterBinder(), (JdbcParameter) registration.getParameterBinder(),
new JdbcParameterBindingImpl( new JdbcParameterBindingImpl(
(JdbcMapping) registration.getParameterType(), parameterType,
binding.getBindValue() bindValue
) )
); );
} }

View File

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

View File

@ -171,12 +171,10 @@ public class AnonymousTupleBasicValuedModelPart implements ModelPart, MappingTyp
creationState.getSqlAstCreationState() creationState.getSqlAstCreationState()
); );
//noinspection unchecked return new BasicResult<>(
return new BasicResult(
sqlSelection.getValuesArrayPosition(), sqlSelection.getValuesArrayPosition(),
resultVariable, resultVariable,
getJavaType(), jdbcMapping,
null,
navigablePath navigablePath
); );
} }
@ -201,7 +199,7 @@ public class AnonymousTupleBasicValuedModelPart implements ModelPart, MappingTyp
); );
return expressionResolver.resolveSqlSelection( return expressionResolver.resolveSqlSelection(
expression, expression,
getJdbcMapping().getJavaTypeDescriptor(), getJdbcMapping().getJdbcJavaType(),
fetchParent, fetchParent,
creationState.getCreationContext().getSessionFactory().getTypeConfiguration() creationState.getCreationContext().getSessionFactory().getTypeConfiguration()
); );
@ -234,7 +232,6 @@ public class AnonymousTupleBasicValuedModelPart implements ModelPart, MappingTyp
fetchParent, fetchParent,
fetchablePath, fetchablePath,
this, this,
null,
fetchTiming, fetchTiming,
creationState 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 SqmPath<T> discriminatorSqmPath = anyDiscriminatorTypeSqmPath.getLhs();
final EntityDomainType<T> entityWithDiscriminator = creationContext.getJpaMetamodel() final EntityDomainType<T> entityWithDiscriminator = creationContext.getJpaMetamodel()
.entity( discriminatorSqmPath.findRoot().getNavigablePath().getLocalName() ); .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.BasicValuedMapping;
import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressible; import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.query.BindableType; import org.hibernate.query.BindableType;
import org.hibernate.query.QueryParameter; import org.hibernate.query.QueryParameter;
import org.hibernate.query.spi.QueryParameterBinding; import org.hibernate.query.spi.QueryParameterBinding;
import org.hibernate.query.spi.QueryParameterBindingValidator; import org.hibernate.query.spi.QueryParameterBindingValidator;
import org.hibernate.query.sqm.SqmExpressible; 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.CoercionException;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.TemporalJavaType; 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 ); final SqmExpressible<? extends T> sqmExpressible = parameterType.resolveExpressible( sessionFactory );
assert sqmExpressible != null; assert sqmExpressible != null;
if ( sqmExpressible instanceof AttributeConverterTypeAdapter ) {
return value;
}
return sqmExpressible.getExpressibleJavaType().coerce( value, this ); return sqmExpressible.getExpressibleJavaType().coerce( value, this );
} }
@ -321,7 +318,8 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
@Override @SuppressWarnings("unchecked") @Override @SuppressWarnings("unchecked")
public boolean setType(MappingModelExpressible<T> type) { public boolean setType(MappingModelExpressible<T> type) {
this.type = 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<?> ) { if ( type instanceof BindableType<?> ) {
final boolean changed = bindType != null && type != bindType; final boolean changed = bindType != null && type != bindType;
this.bindType = (BindableType<T>) type; this.bindType = (BindableType<T>) type;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1001,7 +1001,15 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
} }
final SqmExpressible<T> expressible = resolveInferredType( value, typeInferenceSource, getTypeConfiguration() ); 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( private static <T> SqmExpressible<T> resolveInferredType(
@ -1551,13 +1559,38 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
return literal( value, typeInferenceSource ); return literal( value, typeInferenceSource );
} }
return new ValueBindJpaCriteriaParameter<>( final BindableType<T> bindableType = resolveInferredParameterType(
resolveInferredParameterType( value, typeInferenceSource, getTypeConfiguration() ),
value, 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 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( private static <T> BindableType<T> resolveInferredParameterType(
T value, T value,
SqmExpression<? extends T> typeInferenceSource, 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.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.MappingMetamodel; import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.Bindable; import org.hibernate.metamodel.mapping.Bindable;
import org.hibernate.metamodel.mapping.ConvertibleModelPart; import org.hibernate.metamodel.mapping.ConvertibleModelPart;
import org.hibernate.metamodel.mapping.EntityAssociationMapping; 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.JdbcParameterBindingImpl;
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.exec.spi.JdbcParameterBindings;
import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfiguration;
/** /**
@ -223,10 +223,10 @@ public class SqmUtil {
for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) { for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
final List<JdbcParameter> jdbcParams = jdbcParamsBinds.get( i ); final List<JdbcParameter> jdbcParams = jdbcParamsBinds.get( i );
parameterType.forEachJdbcType( parameterType.forEachJdbcType(
(position, jdbcType) -> { (position, jdbcMapping) -> {
jdbcParameterBindings.addBinding( jdbcParameterBindings.addBinding(
jdbcParams.get( position ), jdbcParams.get( position ),
new JdbcParameterBindingImpl( jdbcType, null ) new JdbcParameterBindingImpl( jdbcMapping, null )
); );
} }
); );
@ -285,37 +285,35 @@ public class SqmUtil {
} }
} }
else { else {
if ( domainParamBinding.getType() instanceof AttributeConverterTypeAdapter final JdbcMapping jdbcMapping;
|| domainParamBinding.getType() instanceof ConvertibleModelPart ) { final BasicValueConverter valueConverter;
final BasicValueConverter valueConverter; if ( domainParamBinding.getType() instanceof JdbcMapping ) {
final JdbcMapping 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 ) { if ( valueConverter != null ) {
final AttributeConverterTypeAdapter<?> adapter = (AttributeConverterTypeAdapter<?>) domainParamBinding.getType(); final Object convertedValue = valueConverter.toRelationalValue( domainParamBinding.getBindValue() );
valueConverter = adapter.getAttributeConverter();
jdbcMapping = adapter.getJdbcMapping(); for ( int i = 0; i < jdbcParamsBinds.size(); i++ ) {
} final List<JdbcParameter> jdbcParams = jdbcParamsBinds.get( i );
else { assert jdbcParams.size() == 1;
final ConvertibleModelPart convertibleModelPart = (ConvertibleModelPart) domainParamBinding.getType(); final JdbcParameter jdbcParameter = jdbcParams.get( 0 );
valueConverter = convertibleModelPart.getValueConverter(); jdbcParameterBindings.addBinding(
jdbcMapping = convertibleModelPart.getJdbcMapping(); jdbcParameter,
new JdbcParameterBindingImpl( jdbcMapping, convertedValue )
);
} }
if ( valueConverter != null ) { continue;
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;
}
} }
final Object bindValue = domainParamBinding.getBindValue(); final Object bindValue = domainParamBinding.getBindValue();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -63,7 +63,6 @@ import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.metamodel.mapping.BasicValuedModelPart; import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.Bindable; import org.hibernate.metamodel.mapping.Bindable;
import org.hibernate.metamodel.mapping.CollectionPart; import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.mapping.ConvertibleModelPart;
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart; import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
import org.hibernate.metamodel.mapping.EmbeddableMappingType; import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart; 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.CastTarget;
import org.hibernate.sql.ast.tree.expression.Collation; import org.hibernate.sql.ast.tree.expression.Collation;
import org.hibernate.sql.ast.tree.expression.ColumnReference; 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.Distinct;
import org.hibernate.sql.ast.tree.expression.Duration; import org.hibernate.sql.ast.tree.expression.Duration;
import org.hibernate.sql.ast.tree.expression.DurationUnit; 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.SqlSelectionImpl;
import org.hibernate.sql.results.internal.StandardEntityGraphTraversalStateImpl; import org.hibernate.sql.results.internal.StandardEntityGraphTraversalStateImpl;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
import org.hibernate.type.CustomType;
import org.hibernate.type.EnumType;
import org.hibernate.type.JavaObjectType; import org.hibernate.type.JavaObjectType;
import org.hibernate.type.SqlTypes; 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.EnumJavaType;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.TemporalJavaType; 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); return new SqlTuple( expressions, mappingModelExpressible);
} }
final MappingModelExpressible<?> inferableExpressible = resolveInferredType(); final MappingModelExpressible<?> inferableExpressible = getInferredValueMapping();
if ( inferableExpressible instanceof ConvertibleModelPart ) { if ( inferableExpressible instanceof BasicValuedMapping ) {
final ConvertibleModelPart convertibleModelPart = (ConvertibleModelPart) inferableExpressible; final BasicValuedMapping basicValuedMapping = (BasicValuedMapping) inferableExpressible;
final BasicValueConverter valueConverter = basicValuedMapping.getJdbcMapping().getValueConverter();
if ( convertibleModelPart.getValueConverter() != null ) { if ( valueConverter != null ) {
return new QueryLiteral<>( final Object value = literal.getLiteralValue();
literal.getLiteralValue(), final Object sqlLiteralValue;
convertibleModelPart // 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 );
}
// 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;
} }
else if ( literalValue instanceof CharSequence ) { else if ( valueConverter.getRelationalJavaType().getJavaTypeClass().isInstance( value ) ) {
discriminatorValue = javaType.fromString( (CharSequence) literalValue ); sqlLiteralValue = value;
} }
else if ( creationContext.getSessionFactory().getJpaMetamodel().getJpaCompliance().isLoadByIdComplianceEnabled() ) { else if ( basicValuedMapping instanceof EntityDiscriminatorMapping ) {
discriminatorValue = literalValue; // 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 { 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( return new QueryLiteral<>(
discriminatorValue 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 @Override
public Object visitEnumLiteral(SqmEnumLiteral<?> sqmEnumLiteral) { public Object visitEnumLiteral(SqmEnumLiteral<?> sqmEnumLiteral) {
final BasicValuedMapping inferrableType = (BasicValuedMapping) resolveInferredType(); final BasicValuedMapping inferrableType = (BasicValuedMapping) resolveInferredType();
if ( inferrableType instanceof ConvertibleModelPart ) { if ( inferrableType != null ) {
final ConvertibleModelPart inferredPart = (ConvertibleModelPart) inferrableType; final BasicValueConverter<Enum<?>,?> valueConverter = (BasicValueConverter<Enum<?>, ?>) inferrableType.getJdbcMapping().getValueConverter();
final BasicValueConverter<Enum<?>,?> valueConverter = inferredPart.getValueConverter(); final Object jdbcValue;
final Object jdbcValue = valueConverter.toRelationalValue( sqmEnumLiteral.getEnumValue() ); if ( valueConverter == null ) {
return new QueryLiteral<>( jdbcValue, inferredPart ); 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 EnumJavaType<?> enumJtd = sqmEnumLiteral.getExpressibleJavaType();
final JdbcType jdbcType = getTypeConfiguration().getJdbcTypeRegistry() final TypeConfiguration typeConfiguration = getTypeConfiguration();
.getDescriptor( SqlTypes.SMALLINT ); final JdbcType jdbcType = typeConfiguration.getJdbcTypeRegistry().getDescriptor( SqlTypes.SMALLINT );
final BasicJavaType<Number> relationalJtd = (BasicJavaType) getTypeConfiguration() final JavaType<Number> relationalJtd = typeConfiguration.getJavaTypeRegistry().getDescriptor( Integer.class );
.getJavaTypeRegistry()
.getDescriptor( Integer.class );
final BasicType<?> jdbcMappingType = getTypeConfiguration().getBasicTypeRegistry().resolve( relationalJtd, jdbcType );
return new ConvertedQueryLiteral( return new QueryLiteral<>(
sqmEnumLiteral.getEnumValue(), sqmEnumLiteral.getEnumValue().ordinal(),
new OrdinalEnumValueConverter<>( enumJtd, jdbcType, relationalJtd ), new CustomType<>(
jdbcMappingType 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.EmbeddableValuedModelPart;
import org.hibernate.metamodel.mapping.EntityAssociationMapping; import org.hibernate.metamodel.mapping.EntityAssociationMapping;
import org.hibernate.metamodel.mapping.EntityValuedModelPart; import org.hibernate.metamodel.mapping.EntityValuedModelPart;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressible; import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.query.BindableType; import org.hibernate.query.BindableType;
import org.hibernate.query.SemanticException; import org.hibernate.query.SemanticException;
import org.hibernate.query.spi.QueryParameterBinding; 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.DomainResult;
import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.basic.BasicResult; import org.hibernate.sql.results.graph.basic.BasicResult;
import org.hibernate.type.descriptor.java.JavaType;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
@ -116,18 +119,30 @@ public class SqmParameterInterpretation implements Expression, DomainResultProdu
.getSessionFactory(); .getSessionFactory();
final SqmExpressible<?> sqmExpressible = nodeType.resolveExpressible( sessionFactory ); 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( final SqlSelection sqlSelection = creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
resolvedExpression, resolvedExpression,
sqmExpressible.getExpressibleJavaType(), jdbcJavaType,
null, null,
sessionFactory.getTypeConfiguration() sessionFactory.getTypeConfiguration()
); );
return new BasicResult<>( return new BasicResult(
sqlSelection.getValuesArrayPosition(), sqlSelection.getValuesArrayPosition(),
resultVariable, resultVariable,
sqmExpressible.getExpressibleJavaType() sqmExpressible.getExpressibleJavaType(),
converter
); );
} }
@ -161,10 +176,18 @@ public class SqmParameterInterpretation implements Expression, DomainResultProdu
.getSessionFactory(); .getSessionFactory();
final SqmExpressible<?> sqmExpressible = nodeType.resolveExpressible( sessionFactory ); 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( return creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
resolvedExpression, resolvedExpression,
sqmExpressible.getExpressibleJavaType(), jdbcJavaType,
null, null,
sessionFactory.getTypeConfiguration() sessionFactory.getTypeConfiguration()
); );

View File

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

View File

@ -59,15 +59,15 @@ public class Conversion
public DomainResult createDomainResult( public DomainResult createDomainResult(
String resultVariable, String resultVariable,
DomainResultCreationState creationState) { DomainResultCreationState creationState) {
return new BasicResult( return new BasicResult<>(
creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection( creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
this, this,
type.getJdbcMapping().getJavaTypeDescriptor(), type.getJdbcMapping().getJdbcJavaType(),
null, null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration() creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()
).getValuesArrayPosition(), ).getValuesArrayPosition(),
resultVariable, resultVariable,
type.getJdbcMapping().getJavaTypeDescriptor() type.getJdbcMapping()
); );
} }
@ -78,7 +78,7 @@ public class Conversion
sqlExpressionResolver.resolveSqlSelection( sqlExpressionResolver.resolveSqlSelection(
this, this,
type.getJdbcMapping().getJavaTypeDescriptor(), type.getJdbcMapping().getJdbcJavaType(),
null, null,
sqlAstCreationState.getCreationContext().getMappingMetamodel().getTypeConfiguration() 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) { public SqmLiteral(T value, SqmExpressible<? extends T> inherentType, NodeBuilder nodeBuilder) {
super( inherentType, nodeBuilder ); super( inherentType, nodeBuilder );
assert value != null; assert value != null && ( inherentType == null || inherentType.getExpressibleJavaType().isInstance( value ) );
this.value = value; this.value = value;
} }

View File

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

View File

@ -3647,9 +3647,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
assert literal.getExpressionType().getJdbcTypeCount() == 1; assert literal.getExpressionType().getJdbcTypeCount() == 1;
final JdbcMapping jdbcMapping = literal.getJdbcMapping(); final JdbcMapping jdbcMapping = literal.getJdbcMapping();
final JdbcLiteralFormatter literalFormatter = jdbcMapping final JdbcLiteralFormatter literalFormatter = jdbcMapping.getJdbcLiteralFormatter();
.getJdbcType()
.getJdbcLiteralFormatter( jdbcMapping.getJavaTypeDescriptor() );
// If we encounter a plain literal in the select clause which has no literal formatter, we must render it as parameter // If we encounter a plain literal in the select clause which has no literal formatter, we must render it as parameter
if ( literalFormatter == null ) { if ( literalFormatter == null ) {
@ -4739,7 +4737,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
else { else {
assert jdbcParameter.getExpressionType().getJdbcTypeCount() == 1; assert jdbcParameter.getExpressionType().getJdbcTypeCount() == 1;
final JdbcMapping jdbcMapping = jdbcParameter.getExpressionType().getJdbcMappings().get( 0 ); final JdbcMapping jdbcMapping = jdbcParameter.getExpressionType().getJdbcMappings().get( 0 );
final JdbcLiteralFormatter literalFormatter = jdbcMapping.getJdbcType().getJdbcLiteralFormatter( jdbcMapping.getJavaTypeDescriptor() ); final JdbcLiteralFormatter literalFormatter = jdbcMapping.getJdbcLiteralFormatter();
if ( literalFormatter == null ) { if ( literalFormatter == null ) {
throw new IllegalArgumentException( "Can't render parameter as literal, no literal formatter found" ); 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; package org.hibernate.sql.ast.tree.expression;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressible; import org.hibernate.metamodel.mapping.MappingModelExpressible;
import org.hibernate.query.sqm.sql.internal.DomainResultProducer; import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
import org.hibernate.sql.ast.SqlAstWalker; import org.hibernate.sql.ast.SqlAstWalker;
@ -48,16 +49,16 @@ public class Any implements Expression, DomainResultProducer {
public DomainResult createDomainResult( public DomainResult createDomainResult(
String resultVariable, String resultVariable,
DomainResultCreationState creationState) { DomainResultCreationState creationState) {
final JavaType javaType = type.getJdbcMappings().get( 0 ).getJavaTypeDescriptor(); final JdbcMapping jdbcMapping = type.getJdbcMappings().get( 0 );
return new BasicResult( return new BasicResult<>(
creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection( creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
this, this,
javaType, jdbcMapping.getJdbcJavaType(),
null, null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration() creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()
).getValuesArrayPosition(), ).getValuesArrayPosition(),
resultVariable, resultVariable,
javaType jdbcMapping
); );
} }
@ -68,7 +69,7 @@ public class Any implements Expression, DomainResultProducer {
sqlExpressionResolver.resolveSqlSelection( sqlExpressionResolver.resolveSqlSelection(
this, this,
type.getJdbcMappings().get( 0 ).getJavaTypeDescriptor(), type.getJdbcMappings().get( 0 ).getJdbcJavaType(),
null, null,
sqlAstCreationState.getCreationContext().getMappingMetamodel().getTypeConfiguration() sqlAstCreationState.getCreationContext().getMappingMetamodel().getTypeConfiguration()
); );

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,15 +8,11 @@ package org.hibernate.sql.ast.tree.expression;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Locale;
import org.hibernate.metamodel.mapping.BasicValuedMapping; import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.metamodel.mapping.ConvertibleModelPart;
import org.hibernate.metamodel.mapping.JdbcMapping; 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.query.sqm.sql.internal.DomainResultProducer;
import org.hibernate.sql.ast.SqlAstWalker; 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.SqlExpressionResolver;
import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.exec.spi.ExecutionContext; import org.hibernate.sql.exec.spi.ExecutionContext;
@ -37,44 +33,9 @@ public class QueryLiteral<T> implements Literal, DomainResultProducer<T> {
private final BasicValuedMapping type; private final BasicValuedMapping type;
public QueryLiteral(T value, BasicValuedMapping type) { public QueryLiteral(T value, BasicValuedMapping type) {
if ( type instanceof ConvertibleModelPart ) { assert value == null || type.getJdbcMapping().getJdbcJavaType().isInstance( value );
final ConvertibleModelPart convertibleModelPart = (ConvertibleModelPart) type; this.value = value;
final BasicValueConverter valueConverter = convertibleModelPart.getValueConverter(); this.type = type;
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;
}
} }
@Override @Override
@ -105,7 +66,7 @@ public class QueryLiteral<T> implements Literal, DomainResultProducer<T> {
.getSqlExpressionResolver(); .getSqlExpressionResolver();
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection( final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
this, this,
type.getMappedType().getMappedJavaType(), type.getJdbcMapping().getJdbcJavaType(),
null, null,
creationState.getSqlAstCreationState() creationState.getSqlAstCreationState()
.getCreationContext() .getCreationContext()
@ -113,10 +74,10 @@ public class QueryLiteral<T> implements Literal, DomainResultProducer<T> {
.getTypeConfiguration() .getTypeConfiguration()
); );
return new BasicResult( return new BasicResult<>(
sqlSelection.getValuesArrayPosition(), sqlSelection.getValuesArrayPosition(),
resultVariable, resultVariable,
type.getMappedType().getMappedJavaType() type.getJdbcMapping()
); );
} }
@ -126,19 +87,10 @@ public class QueryLiteral<T> implements Literal, DomainResultProducer<T> {
int startPosition, int startPosition,
JdbcParameterBindings jdbcParameterBindings, JdbcParameterBindings jdbcParameterBindings,
ExecutionContext executionContext) throws SQLException { 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 //noinspection unchecked
type.getJdbcMapping().getJdbcValueBinder().bind( type.getJdbcMapping().getJdbcValueBinder().bind(
statement, statement,
literalValue, getLiteralValue(),
startPosition, startPosition,
executionContext.getSession() executionContext.getSession()
); );
@ -148,7 +100,7 @@ public class QueryLiteral<T> implements Literal, DomainResultProducer<T> {
public void applySqlSelections(DomainResultCreationState creationState) { public void applySqlSelections(DomainResultCreationState creationState) {
creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection( creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
this, this,
type.getJdbcMapping().getJavaTypeDescriptor(), type.getJdbcMapping().getJdbcJavaType(),
null, null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration() 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 JavaType javaType = ( (SqmExpressible<?>) valueMapping ).getExpressibleJavaType();
final int[] valuesArrayPositions = new int[expressions.size()]; final int[] valuesArrayPositions = new int[expressions.size()];
for ( int i = 0; i < expressions.size(); i++ ) { for ( int i = 0; i < expressions.size(); i++ ) {
final Expression expression = expressions.get( i );
valuesArrayPositions[i] = creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection( valuesArrayPositions[i] = creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
expressions.get( i ), expression,
javaType, expression.getExpressionType().getJdbcMappings().get( 0 ).getJdbcJavaType(),
null, null,
creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration() creationState.getSqlAstCreationState().getCreationContext().getMappingMetamodel().getTypeConfiguration()
).getValuesArrayPosition(); ).getValuesArrayPosition();

View File

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

View File

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

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