HHH-17739 fix NPE for field with unsupported collection type
cleanups and warning fixes in TypeConfiguration and BasicValue
This commit is contained in:
parent
f5e1d1cd73
commit
6c6c92e88d
|
@ -40,7 +40,6 @@ import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.jdbc.Size;
|
import org.hibernate.engine.jdbc.Size;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
@ -82,6 +81,7 @@ import jakarta.persistence.EnumType;
|
||||||
import jakarta.persistence.TemporalType;
|
import jakarta.persistence.TemporalType;
|
||||||
|
|
||||||
import static java.lang.Boolean.parseBoolean;
|
import static java.lang.Boolean.parseBoolean;
|
||||||
|
import static org.hibernate.internal.util.ReflectHelper.reflectedPropertyType;
|
||||||
import static org.hibernate.internal.util.collections.CollectionHelper.isNotEmpty;
|
import static org.hibernate.internal.util.collections.CollectionHelper.isNotEmpty;
|
||||||
import static org.hibernate.mapping.MappingHelper.injectParameters;
|
import static org.hibernate.mapping.MappingHelper.injectParameters;
|
||||||
|
|
||||||
|
@ -103,6 +103,7 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
|
||||||
private Function<TypeConfiguration, java.lang.reflect.Type> implicitJavaTypeAccess;
|
private Function<TypeConfiguration, java.lang.reflect.Type> implicitJavaTypeAccess;
|
||||||
|
|
||||||
private EnumType enumerationStyle;
|
private EnumType enumerationStyle;
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
private TemporalType temporalPrecision;
|
private TemporalType temporalPrecision;
|
||||||
private TimeZoneStorageType timeZoneStorageType;
|
private TimeZoneStorageType timeZoneStorageType;
|
||||||
private boolean isSoftDelete;
|
private boolean isSoftDelete;
|
||||||
|
@ -233,8 +234,7 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
|
||||||
@Override
|
@Override
|
||||||
public long getColumnLength() {
|
public long getColumnLength() {
|
||||||
final Selectable selectable = getColumn();
|
final Selectable selectable = getColumn();
|
||||||
if ( selectable instanceof Column ) {
|
if ( selectable instanceof Column column ) {
|
||||||
final Column column = (Column) selectable;
|
|
||||||
final Long length = column.getLength();
|
final Long length = column.getLength();
|
||||||
return length == null ? NO_COLUMN_LENGTH : length;
|
return length == null ? NO_COLUMN_LENGTH : length;
|
||||||
}
|
}
|
||||||
|
@ -246,10 +246,10 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
|
||||||
@Override
|
@Override
|
||||||
public int getColumnPrecision() {
|
public int getColumnPrecision() {
|
||||||
final Selectable selectable = getColumn();
|
final Selectable selectable = getColumn();
|
||||||
if ( selectable instanceof Column ) {
|
if ( selectable instanceof Column column ) {
|
||||||
final Column column = (Column) selectable;
|
final Integer temporalPrecision = column.getTemporalPrecision();
|
||||||
if ( column.getTemporalPrecision() != null ) {
|
if ( temporalPrecision != null ) {
|
||||||
return column.getTemporalPrecision();
|
return temporalPrecision;
|
||||||
}
|
}
|
||||||
final Integer precision = column.getPrecision();
|
final Integer precision = column.getPrecision();
|
||||||
return precision == null ? NO_COLUMN_PRECISION : precision;
|
return precision == null ? NO_COLUMN_PRECISION : precision;
|
||||||
|
@ -262,8 +262,7 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
|
||||||
@Override
|
@Override
|
||||||
public int getColumnScale() {
|
public int getColumnScale() {
|
||||||
final Selectable selectable = getColumn();
|
final Selectable selectable = getColumn();
|
||||||
if ( selectable instanceof Column ) {
|
if ( selectable instanceof Column column ) {
|
||||||
final Column column = (Column) selectable;
|
|
||||||
final Integer scale = column.getScale();
|
final Integer scale = column.getScale();
|
||||||
return scale == null ? NO_COLUMN_SCALE : scale;
|
return scale == null ? NO_COLUMN_SCALE : scale;
|
||||||
}
|
}
|
||||||
|
@ -282,10 +281,10 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
|
||||||
@Override
|
@Override
|
||||||
public void copyTypeFrom(SimpleValue sourceValue) {
|
public void copyTypeFrom(SimpleValue sourceValue) {
|
||||||
super.copyTypeFrom( sourceValue );
|
super.copyTypeFrom( sourceValue );
|
||||||
if ( sourceValue instanceof BasicValue ) {
|
if ( sourceValue instanceof BasicValue basicValue ) {
|
||||||
final BasicValue basicValue = (BasicValue) sourceValue;
|
resolution = basicValue.resolution;
|
||||||
this.resolution = basicValue.resolution;
|
implicitJavaTypeAccess =
|
||||||
this.implicitJavaTypeAccess = (typeConfiguration) -> basicValue.implicitJavaTypeAccess.apply( typeConfiguration );
|
typeConfiguration -> basicValue.implicitJavaTypeAccess.apply( typeConfiguration );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,55 +445,71 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
|
||||||
getBuildingContext()
|
getBuildingContext()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
else if ( isVersion() ) {
|
||||||
if ( isVersion() ) {
|
|
||||||
return VersionResolution.from( implicitJavaTypeAccess, timeZoneStorageType, getBuildingContext() );
|
return VersionResolution.from( implicitJavaTypeAccess, timeZoneStorageType, getBuildingContext() );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// determine JavaType if we can
|
||||||
|
final BasicJavaType<?> explicitJavaType = getExplicitJavaType();
|
||||||
|
final JavaType<?> javaType = determineJavaType( explicitJavaType );
|
||||||
|
final ConverterDescriptor converterDescriptor = getConverterDescriptor( javaType );
|
||||||
|
return converterDescriptor != null
|
||||||
|
? converterResolution( javaType, converterDescriptor )
|
||||||
|
: resolution( explicitJavaType, javaType );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// determine JavaType if we can
|
private BasicJavaType<?> getExplicitJavaType() {
|
||||||
final BasicJavaType<?> explicitJavaType = explicitJavaTypeAccess == null
|
return explicitJavaTypeAccess == null ? null
|
||||||
? null
|
|
||||||
: explicitJavaTypeAccess.apply( getTypeConfiguration() );
|
: explicitJavaTypeAccess.apply( getTypeConfiguration() );
|
||||||
|
}
|
||||||
|
|
||||||
JavaType<?> javaType = determineJavaType( explicitJavaType );
|
private ConverterDescriptor getConverterDescriptor(JavaType<?> javaType) {
|
||||||
ConverterDescriptor attributeConverterDescriptor = getAttributeConverterDescriptor();
|
final ConverterDescriptor converterDescriptor = getAttributeConverterDescriptor();
|
||||||
|
|
||||||
if ( isSoftDelete() ) {
|
if ( isSoftDelete() ) {
|
||||||
assert attributeConverterDescriptor != null;
|
assert converterDescriptor != null;
|
||||||
final boolean conversionWasUnspecified = SoftDelete.UnspecifiedConversion.class.equals( attributeConverterDescriptor.getAttributeConverterClass() );
|
final ConverterDescriptor softDeleteConverterDescriptor =
|
||||||
if ( conversionWasUnspecified ) {
|
getSoftDeleteConverterDescriptor( converterDescriptor, javaType);
|
||||||
final JdbcType jdbcType = BooleanJdbcType.INSTANCE.resolveIndicatedType( this, javaType );
|
return getSoftDeleteStrategy() == SoftDeleteType.ACTIVE
|
||||||
if ( jdbcType.isNumber() ) {
|
? new ReversedConverterDescriptor<>( softDeleteConverterDescriptor )
|
||||||
attributeConverterDescriptor = new InstanceBasedConverterDescriptor(
|
: softDeleteConverterDescriptor;
|
||||||
NumericBooleanConverter.INSTANCE,
|
}
|
||||||
getBuildingContext().getBootstrapContext().getClassmateContext()
|
else {
|
||||||
);
|
return converterDescriptor;
|
||||||
}
|
}
|
||||||
else if ( jdbcType.isString() ) {
|
}
|
||||||
// here we pick 'T' / 'F' storage, though 'Y' / 'N' is equally valid - its 50/50
|
|
||||||
attributeConverterDescriptor = new InstanceBasedConverterDescriptor(
|
|
||||||
TrueFalseConverter.INSTANCE,
|
|
||||||
getBuildingContext().getBootstrapContext().getClassmateContext()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// should indicate BIT or BOOLEAN == no conversion needed
|
|
||||||
// - we still create the converter to properly set up JDBC type, etc
|
|
||||||
attributeConverterDescriptor = new InstanceBasedConverterDescriptor(
|
|
||||||
PassThruSoftDeleteConverter.INSTANCE,
|
|
||||||
getBuildingContext().getBootstrapContext().getClassmateContext()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( getSoftDeleteStrategy() == SoftDeleteType.ACTIVE ) {
|
private ConverterDescriptor getSoftDeleteConverterDescriptor(
|
||||||
attributeConverterDescriptor = new ReversedConverterDescriptor<>( attributeConverterDescriptor );
|
ConverterDescriptor attributeConverterDescriptor, JavaType<?> javaType) {
|
||||||
|
final boolean conversionWasUnspecified =
|
||||||
|
SoftDelete.UnspecifiedConversion.class.equals( attributeConverterDescriptor.getAttributeConverterClass() );
|
||||||
|
if ( conversionWasUnspecified ) {
|
||||||
|
final JdbcType jdbcType = BooleanJdbcType.INSTANCE.resolveIndicatedType( this, javaType);
|
||||||
|
if ( jdbcType.isNumber() ) {
|
||||||
|
return new InstanceBasedConverterDescriptor(
|
||||||
|
NumericBooleanConverter.INSTANCE,
|
||||||
|
getBuildingContext().getBootstrapContext().getClassmateContext()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if ( jdbcType.isString() ) {
|
||||||
|
// here we pick 'T' / 'F' storage, though 'Y' / 'N' is equally valid - its 50/50
|
||||||
|
return new InstanceBasedConverterDescriptor(
|
||||||
|
TrueFalseConverter.INSTANCE,
|
||||||
|
getBuildingContext().getBootstrapContext().getClassmateContext()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// should indicate BIT or BOOLEAN == no conversion needed
|
||||||
|
// - we still create the converter to properly set up JDBC type, etc
|
||||||
|
return new InstanceBasedConverterDescriptor(
|
||||||
|
PassThruSoftDeleteConverter.INSTANCE,
|
||||||
|
getBuildingContext().getBootstrapContext().getClassmateContext()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
return attributeConverterDescriptor != null
|
return attributeConverterDescriptor;
|
||||||
? converterResolution( javaType, attributeConverterDescriptor )
|
}
|
||||||
: resolution( explicitJavaType, javaType );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ReversedConverterDescriptor<R> implements ConverterDescriptor {
|
private static class ReversedConverterDescriptor<R> implements ConverterDescriptor {
|
||||||
|
@ -675,11 +690,10 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
|
||||||
getBuildingContext()
|
getBuildingContext()
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( javaType instanceof BasicPluralJavaType<?>
|
if ( javaType instanceof BasicPluralJavaType<?> containerJtd
|
||||||
&& !attributeConverterDescriptor.getDomainValueResolvedType().getErasedType()
|
&& !attributeConverterDescriptor.getDomainValueResolvedType().getErasedType()
|
||||||
.isAssignableFrom( javaType.getJavaTypeClass() ) ) {
|
.isAssignableFrom( javaType.getJavaTypeClass() ) ) {
|
||||||
// In this case, the converter applies to the element of a BasicPluralJavaType
|
// In this case, the converter applies to the element of a BasicPluralJavaType
|
||||||
final BasicPluralJavaType<?> containerJtd = (BasicPluralJavaType<?>) javaType;
|
|
||||||
final BasicType registeredElementType = converterResolution.getLegacyResolvedBasicType();
|
final BasicType registeredElementType = converterResolution.getLegacyResolvedBasicType();
|
||||||
final Selectable column = getColumn();
|
final Selectable column = getColumn();
|
||||||
final BasicType<?> registeredType = registeredElementType == null ? null
|
final BasicType<?> registeredType = registeredElementType == null ? null
|
||||||
|
@ -729,66 +743,76 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
|
||||||
}
|
}
|
||||||
|
|
||||||
private JavaType<?> determineReflectedJavaType() {
|
private JavaType<?> determineReflectedJavaType() {
|
||||||
final java.lang.reflect.Type impliedJavaType;
|
|
||||||
|
|
||||||
final TypeConfiguration typeConfiguration = getTypeConfiguration();
|
final TypeConfiguration typeConfiguration = getTypeConfiguration();
|
||||||
|
final java.lang.reflect.Type impliedJavaType = impliedJavaType( typeConfiguration );
|
||||||
|
if ( impliedJavaType == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resolvedJavaType = impliedJavaType;
|
||||||
|
return javaType( typeConfiguration, impliedJavaType );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private java.lang.reflect.Type impliedJavaType(TypeConfiguration typeConfiguration) {
|
||||||
if ( resolvedJavaType != null ) {
|
if ( resolvedJavaType != null ) {
|
||||||
impliedJavaType = resolvedJavaType;
|
return resolvedJavaType;
|
||||||
}
|
}
|
||||||
else if ( implicitJavaTypeAccess != null ) {
|
else if ( implicitJavaTypeAccess != null ) {
|
||||||
impliedJavaType = implicitJavaTypeAccess.apply( typeConfiguration );
|
return implicitJavaTypeAccess.apply(typeConfiguration);
|
||||||
}
|
}
|
||||||
else if ( ownerName != null && propertyName != null ) {
|
else if ( ownerName != null && propertyName != null ) {
|
||||||
impliedJavaType = ReflectHelper.reflectedPropertyType(
|
return reflectedPropertyType( ownerName, propertyName,
|
||||||
ownerName,
|
getServiceRegistry().requireService( ClassLoaderService.class ) );
|
||||||
propertyName,
|
|
||||||
getServiceRegistry().requireService( ClassLoaderService.class )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resolvedJavaType = impliedJavaType;
|
private JavaType<Object> javaType(TypeConfiguration typeConfiguration, java.lang.reflect.Type impliedJavaType) {
|
||||||
|
final JavaType<Object> javaType = typeConfiguration.getJavaTypeRegistry().findDescriptor( impliedJavaType );
|
||||||
if ( impliedJavaType == null ) {
|
return javaType == null ? specialJavaType( typeConfiguration, impliedJavaType ) : javaType;
|
||||||
return null;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
private JavaType<Object> specialJavaType(
|
||||||
|
TypeConfiguration typeConfiguration,
|
||||||
|
java.lang.reflect.Type impliedJavaType) {
|
||||||
final JavaTypeRegistry javaTypeRegistry = typeConfiguration.getJavaTypeRegistry();
|
final JavaTypeRegistry javaTypeRegistry = typeConfiguration.getJavaTypeRegistry();
|
||||||
final JavaType<Object> javaType = javaTypeRegistry.findDescriptor( impliedJavaType );
|
if ( jdbcTypeCode != null ) {
|
||||||
final MutabilityPlan<Object> explicitMutabilityPlan = explicitMutabilityPlanAccess != null
|
// Construct special JavaType instances for JSON/XML types which can report recommended JDBC types
|
||||||
? explicitMutabilityPlanAccess.apply( typeConfiguration )
|
// and implement toString/fromString as well as copying based on FormatMapper operations
|
||||||
: null;
|
switch ( jdbcTypeCode ) {
|
||||||
final MutabilityPlan<Object> determinedMutabilityPlan = explicitMutabilityPlan != null
|
case SqlTypes.JSON:
|
||||||
|
final JavaType<Object> jsonJavaType =
|
||||||
|
new JsonJavaType<>( impliedJavaType,
|
||||||
|
mutabilityPlan( typeConfiguration, impliedJavaType ),
|
||||||
|
typeConfiguration );
|
||||||
|
javaTypeRegistry.addDescriptor( jsonJavaType );
|
||||||
|
return jsonJavaType;
|
||||||
|
case SqlTypes.SQLXML:
|
||||||
|
final JavaType<Object> xmlJavaType =
|
||||||
|
new XmlJavaType<>( impliedJavaType,
|
||||||
|
mutabilityPlan( typeConfiguration, impliedJavaType ),
|
||||||
|
typeConfiguration );
|
||||||
|
javaTypeRegistry.addDescriptor( xmlJavaType );
|
||||||
|
return xmlJavaType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return javaTypeRegistry.resolveDescriptor( impliedJavaType );
|
||||||
|
}
|
||||||
|
|
||||||
|
private MutabilityPlan<Object> mutabilityPlan(
|
||||||
|
TypeConfiguration typeConfiguration, java.lang.reflect.Type impliedJavaType) {
|
||||||
|
final MutabilityPlan<Object> explicitMutabilityPlan = getExplicitMutabilityPlan();
|
||||||
|
return explicitMutabilityPlan != null
|
||||||
? explicitMutabilityPlan
|
? explicitMutabilityPlan
|
||||||
: RegistryHelper.INSTANCE.determineMutabilityPlan( impliedJavaType, typeConfiguration );
|
: RegistryHelper.INSTANCE.determineMutabilityPlan( impliedJavaType, typeConfiguration );
|
||||||
if ( javaType == null ) {
|
}
|
||||||
if ( jdbcTypeCode != null ) {
|
|
||||||
// Construct special JavaType instances for JSON/XML types which can report recommended JDBC types
|
private MutabilityPlan<Object> getExplicitMutabilityPlan() {
|
||||||
// and implement toString/fromString as well as copying based on FormatMapper operations
|
return explicitMutabilityPlanAccess == null ? null
|
||||||
switch ( jdbcTypeCode ) {
|
: explicitMutabilityPlanAccess.apply( getTypeConfiguration() );
|
||||||
case SqlTypes.JSON:
|
|
||||||
final JavaType<Object> jsonJavaType = new JsonJavaType<>(
|
|
||||||
impliedJavaType,
|
|
||||||
determinedMutabilityPlan,
|
|
||||||
typeConfiguration
|
|
||||||
);
|
|
||||||
javaTypeRegistry.addDescriptor( jsonJavaType );
|
|
||||||
return jsonJavaType;
|
|
||||||
case SqlTypes.SQLXML:
|
|
||||||
final JavaType<Object> xmlJavaType = new XmlJavaType<>(
|
|
||||||
impliedJavaType,
|
|
||||||
determinedMutabilityPlan,
|
|
||||||
typeConfiguration
|
|
||||||
);
|
|
||||||
javaTypeRegistry.addDescriptor( xmlJavaType );
|
|
||||||
return xmlJavaType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return javaTypeRegistry.resolveDescriptor( impliedJavaType );
|
|
||||||
}
|
|
||||||
return javaType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Resolution<?> interpretExplicitlyNamedType(
|
private static Resolution<?> interpretExplicitlyNamedType(
|
||||||
|
@ -1064,8 +1088,7 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
|
||||||
? FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( explicitCustomType )
|
? FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( explicitCustomType )
|
||||||
: getUserTypeBean( explicitCustomType, properties ).getBeanInstance();
|
: getUserTypeBean( explicitCustomType, properties ).getBeanInstance();
|
||||||
|
|
||||||
if ( typeInstance instanceof TypeConfigurationAware ) {
|
if ( typeInstance instanceof TypeConfigurationAware configurationAware ) {
|
||||||
final TypeConfigurationAware configurationAware = (TypeConfigurationAware) typeInstance;
|
|
||||||
configurationAware.setTypeConfiguration( getTypeConfiguration() );
|
configurationAware.setTypeConfiguration( getTypeConfiguration() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1096,11 +1119,12 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public void setTemporalPrecision(TemporalType temporalPrecision) {
|
public void setTemporalPrecision(TemporalType temporalPrecision) {
|
||||||
this.temporalPrecision = temporalPrecision;
|
this.temporalPrecision = temporalPrecision;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override @SuppressWarnings("deprecation")
|
||||||
public TemporalType getTemporalPrecision() {
|
public TemporalType getTemporalPrecision() {
|
||||||
return temporalPrecision;
|
return temporalPrecision;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,59 +68,46 @@ public class BasicTypeRegistry implements Serializable {
|
||||||
if ( typeReference == null ) {
|
if ( typeReference == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if ( !name.equals( typeReference.getName() ) ) {
|
else if ( !name.equals( typeReference.getName() ) ) {
|
||||||
final BasicType<?> basicType = typesByName.get( typeReference.getName() );
|
final BasicType<?> basicType = typesByName.get( typeReference.getName() );
|
||||||
if ( basicType != null ) {
|
if ( basicType != null ) {
|
||||||
return basicType;
|
return basicType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final JavaType<Object> javaType = typeConfiguration.getJavaTypeRegistry().getDescriptor(
|
|
||||||
typeReference.getBindableJavaType()
|
return createBasicType( name, typeReference );
|
||||||
);
|
}
|
||||||
final JdbcType jdbcType = typeConfiguration.getJdbcTypeRegistry().getDescriptor(
|
|
||||||
typeReference.getSqlTypeCode()
|
private BasicType<?> createBasicType(String name, BasicTypeReference<?> typeReference) {
|
||||||
);
|
final JavaType<Object> javaType =
|
||||||
final BasicType<?> type;
|
typeConfiguration.getJavaTypeRegistry()
|
||||||
|
.getDescriptor( typeReference.getBindableJavaType() );
|
||||||
|
final JdbcType jdbcType =
|
||||||
|
typeConfiguration.getJdbcTypeRegistry()
|
||||||
|
.getDescriptor( typeReference.getSqlTypeCode() );
|
||||||
|
final BasicType<?> createdType = createBasicType( typeReference, javaType, jdbcType );
|
||||||
|
primeRegistryEntry( createdType );
|
||||||
|
typesByName.put( typeReference.getName(), createdType );
|
||||||
|
typesByName.put( name, createdType );
|
||||||
|
return createdType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BasicType<?> createBasicType(
|
||||||
|
BasicTypeReference<?> typeReference, JavaType<Object> javaType, JdbcType jdbcType) {
|
||||||
|
final String name = typeReference.getName();
|
||||||
if ( typeReference.getConverter() == null ) {
|
if ( typeReference.getConverter() == null ) {
|
||||||
if ( typeReference.isForceImmutable() ) {
|
return typeReference.isForceImmutable()
|
||||||
type = new ImmutableNamedBasicTypeImpl<>(
|
? new ImmutableNamedBasicTypeImpl<>( javaType, jdbcType, name )
|
||||||
javaType,
|
: new NamedBasicTypeImpl<>( javaType, jdbcType, name );
|
||||||
jdbcType,
|
|
||||||
typeReference.getName()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
type = new NamedBasicTypeImpl<>(
|
|
||||||
javaType,
|
|
||||||
jdbcType,
|
|
||||||
typeReference.getName()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//noinspection unchecked
|
final BasicValueConverter<?, ?> converter = typeReference.getConverter();
|
||||||
final BasicValueConverter<Object, ?> converter = (BasicValueConverter<Object, ?>) typeReference.getConverter();
|
|
||||||
assert javaType == converter.getDomainJavaType();
|
assert javaType == converter.getDomainJavaType();
|
||||||
if ( typeReference.isForceImmutable() ) {
|
return typeReference.isForceImmutable()
|
||||||
type = new CustomMutabilityConvertedBasicTypeImpl<>(
|
? new CustomMutabilityConvertedBasicTypeImpl<>( name, jdbcType, converter,
|
||||||
typeReference.getName(),
|
ImmutableMutabilityPlan.instance() )
|
||||||
jdbcType,
|
: new ConvertedBasicTypeImpl<>( name, jdbcType, converter );
|
||||||
converter,
|
|
||||||
ImmutableMutabilityPlan.instance()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
type = new ConvertedBasicTypeImpl<>(
|
|
||||||
typeReference.getName(),
|
|
||||||
jdbcType,
|
|
||||||
converter
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
primeRegistryEntry( type );
|
|
||||||
typesByName.put( typeReference.getName(), type );
|
|
||||||
typesByName.put( name, type );
|
|
||||||
return type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <J> BasicType<J> getRegisteredType(java.lang.reflect.Type javaType) {
|
public <J> BasicType<J> getRegisteredType(java.lang.reflect.Type javaType) {
|
||||||
|
@ -144,10 +131,7 @@ public class BasicTypeRegistry implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public <J> BasicType<J> resolve(JavaType<J> javaType, int sqlTypeCode) {
|
public <J> BasicType<J> resolve(JavaType<J> javaType, int sqlTypeCode) {
|
||||||
return resolve(
|
return resolve( javaType, typeConfiguration.getJdbcTypeRegistry().getDescriptor( sqlTypeCode ) );
|
||||||
javaType,
|
|
||||||
typeConfiguration.getJdbcTypeRegistry().getDescriptor( sqlTypeCode )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -158,38 +142,37 @@ public class BasicTypeRegistry implements Serializable {
|
||||||
return resolve(
|
return resolve(
|
||||||
javaType,
|
javaType,
|
||||||
jdbcType,
|
jdbcType,
|
||||||
() -> {
|
() -> resolvedType( javaType, jdbcType )
|
||||||
if ( javaType instanceof BasicPluralJavaType<?> && jdbcType instanceof ArrayJdbcType ) {
|
|
||||||
//noinspection unchecked
|
|
||||||
final BasicPluralJavaType<Object> pluralJavaType = (BasicPluralJavaType<Object>) javaType;
|
|
||||||
final BasicType<Object> elementType = resolve(
|
|
||||||
pluralJavaType.getElementJavaType(),
|
|
||||||
( (ArrayJdbcType) jdbcType ).getElementJdbcType()
|
|
||||||
);
|
|
||||||
final BasicType<?> resolvedType = pluralJavaType.resolveType(
|
|
||||||
typeConfiguration,
|
|
||||||
typeConfiguration.getCurrentBaseSqlTypeIndicators().getDialect(),
|
|
||||||
elementType,
|
|
||||||
null,
|
|
||||||
typeConfiguration.getCurrentBaseSqlTypeIndicators()
|
|
||||||
);
|
|
||||||
if ( resolvedType instanceof BasicPluralType<?, ?> ) {
|
|
||||||
register( resolvedType );
|
|
||||||
}
|
|
||||||
//noinspection unchecked
|
|
||||||
return (BasicType<J>) resolvedType;
|
|
||||||
}
|
|
||||||
return new BasicTypeImpl<>( javaType, jdbcType );
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <J> BasicType<J> resolve(JavaType<J> javaType, JdbcType jdbcType, String baseTypeName) {
|
private <J> BasicType<J> resolvedType(JavaType<J> javaType, JdbcType jdbcType) {
|
||||||
return resolve(
|
if ( javaType instanceof BasicPluralJavaType<?> pluralJavaType
|
||||||
javaType,
|
&& jdbcType instanceof ArrayJdbcType arrayType ) {
|
||||||
jdbcType,
|
//noinspection unchecked
|
||||||
() -> new NamedBasicTypeImpl<>( javaType, jdbcType, baseTypeName )
|
return (BasicType<J>) resolvedType( arrayType, pluralJavaType );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new BasicTypeImpl<>( javaType, jdbcType );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <E> BasicType<?> resolvedType(ArrayJdbcType arrayType, BasicPluralJavaType<E> castPluralJavaType) {
|
||||||
|
final BasicType<?> resolvedType = castPluralJavaType.resolveType(
|
||||||
|
typeConfiguration,
|
||||||
|
typeConfiguration.getCurrentBaseSqlTypeIndicators().getDialect(),
|
||||||
|
resolve( castPluralJavaType.getElementJavaType(), arrayType.getElementJdbcType() ),
|
||||||
|
null,
|
||||||
|
typeConfiguration.getCurrentBaseSqlTypeIndicators()
|
||||||
);
|
);
|
||||||
|
if ( resolvedType instanceof BasicPluralType<?,?> ) {
|
||||||
|
register( resolvedType );
|
||||||
|
}
|
||||||
|
return resolvedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <J> BasicType<J> resolve(JavaType<J> javaType, JdbcType jdbcType, String baseTypeName) {
|
||||||
|
return resolve( javaType, jdbcType, () -> new NamedBasicTypeImpl<>( javaType, jdbcType, baseTypeName ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -197,34 +180,48 @@ public class BasicTypeRegistry implements Serializable {
|
||||||
* JdbcType combo or create (and register) one.
|
* JdbcType combo or create (and register) one.
|
||||||
*/
|
*/
|
||||||
public <J> BasicType<J> resolve(JavaType<J> javaType, JdbcType jdbcType, Supplier<BasicType<J>> creator) {
|
public <J> BasicType<J> resolve(JavaType<J> javaType, JdbcType jdbcType, Supplier<BasicType<J>> creator) {
|
||||||
final Map<JavaType<?>, BasicType<?>> typeByJavaTypeForJdbcType = registryValues.computeIfAbsent(
|
final BasicType<?> registeredBasicType = registryForJdbcType( jdbcType ).get( javaType );
|
||||||
jdbcType,
|
//noinspection unchecked
|
||||||
key -> new ConcurrentHashMap<>()
|
return registeredBasicType != null
|
||||||
);
|
? (BasicType<J>) registeredBasicType
|
||||||
|
: createIfUnregistered( javaType, jdbcType, creator );
|
||||||
|
}
|
||||||
|
|
||||||
final BasicType<?> foundBasicType = typeByJavaTypeForJdbcType.get( javaType );
|
private <J> BasicType<J> createIfUnregistered(
|
||||||
if ( foundBasicType != null ) {
|
JavaType<J> javaType,
|
||||||
//noinspection unchecked
|
JdbcType jdbcType,
|
||||||
return (BasicType<J>) foundBasicType;
|
Supplier<BasicType<J>> creator) {
|
||||||
}
|
|
||||||
// Before simply creating the type, we try to find if there is a registered type for this java type,
|
// Before simply creating the type, we try to find if there is a registered type for this java type,
|
||||||
// and if so, if the jdbc type descriptor matches. Unless it does, we at least reuse the name
|
// and if so, if the jdbc type descriptor matches. Unless it does, we at least reuse the name
|
||||||
final BasicType<J> registeredType = getRegisteredType( javaType.getJavaType() );
|
final BasicType<J> registeredType = getRegisteredType( javaType.getJavaType() );
|
||||||
if ( registeredType != null && registeredType.getJdbcType() == jdbcType && registeredType.getMappedJavaType() == javaType ) {
|
if ( registeredTypeMatches( javaType, jdbcType, registeredType ) ) {
|
||||||
return registeredType;
|
return registeredType;
|
||||||
}
|
}
|
||||||
final BasicType<J> createdBasicType = creator.get();
|
else {
|
||||||
typeByJavaTypeForJdbcType.put( javaType, createdBasicType );
|
final BasicType<J> createdType = creator.get();
|
||||||
|
register( javaType, jdbcType, createdType );
|
||||||
|
return createdType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if we are still building mappings, register this ad-hoc type
|
private static <J> boolean registeredTypeMatches(JavaType<J> javaType, JdbcType jdbcType, BasicType<J> registeredType) {
|
||||||
// via a unique code. this is to support envers
|
return registeredType != null
|
||||||
try {
|
&& registeredType.getJdbcType() == jdbcType
|
||||||
typeConfiguration.getMetadataBuildingContext().getBootstrapContext()
|
&& registeredType.getMappedJavaType() == javaType;
|
||||||
.registerAdHocBasicType( createdBasicType );
|
}
|
||||||
|
|
||||||
|
private <J> void register(JavaType<J> javaType, JdbcType jdbcType, BasicType<J> createdType) {
|
||||||
|
if ( createdType != null ) {
|
||||||
|
registryForJdbcType( jdbcType ).put( javaType, createdType );
|
||||||
|
// if we are still building mappings, register this adhoc
|
||||||
|
// type via a unique code. (This is to support Envers.)
|
||||||
|
try {
|
||||||
|
typeConfiguration.getMetadataBuildingContext().getBootstrapContext()
|
||||||
|
.registerAdHocBasicType( createdType );
|
||||||
|
}
|
||||||
|
catch (Exception ignore) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ignore) {
|
|
||||||
}
|
|
||||||
return createdBasicType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -260,16 +257,12 @@ public class BasicTypeRegistry implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyOrOverwriteEntry(BasicType<?> type) {
|
private void applyOrOverwriteEntry(BasicType<?> type) {
|
||||||
final Map<JavaType<?>, BasicType<?>> typeByJavaTypeForJdbcType = registryValues.computeIfAbsent(
|
final JdbcType jdbcType = type.getJdbcType();
|
||||||
type.getJdbcType(),
|
final BasicType<?> existing = registryForJdbcType( jdbcType ).put( type.getMappedJavaType(), type );
|
||||||
jdbcType -> new ConcurrentHashMap<>()
|
|
||||||
);
|
|
||||||
|
|
||||||
final BasicType<?> existing = typeByJavaTypeForJdbcType.put( type.getMappedJavaType(), type );
|
|
||||||
if ( existing != null ) {
|
if ( existing != null ) {
|
||||||
LOG.debugf(
|
LOG.debugf(
|
||||||
"BasicTypeRegistry registration overwritten (%s + %s); previous =`%s`",
|
"BasicTypeRegistry registration overwritten (%s + %s); previous =`%s`",
|
||||||
type.getJdbcType().getFriendlyName(),
|
jdbcType.getFriendlyName(),
|
||||||
type.getJavaTypeDescriptor(),
|
type.getJavaTypeDescriptor(),
|
||||||
existing
|
existing
|
||||||
);
|
);
|
||||||
|
@ -360,26 +353,25 @@ public class BasicTypeRegistry implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void primeRegistryEntry(BasicType<?> type) {
|
private void primeRegistryEntry(BasicType<?> type) {
|
||||||
final Map<JavaType<?>, BasicType<?>> typeByJavaTypeForJdbcType = registryValues.computeIfAbsent(
|
final JdbcType jdbcType = type.getJdbcType();
|
||||||
type.getJdbcType(),
|
final BasicType<?> existing = registryForJdbcType( jdbcType ).get( type.getMappedJavaType() );
|
||||||
jdbcType -> new ConcurrentHashMap<>()
|
|
||||||
);
|
|
||||||
|
|
||||||
final BasicType<?> existing = typeByJavaTypeForJdbcType.get( type.getMappedJavaType() );
|
|
||||||
|
|
||||||
if ( existing != null ) {
|
if ( existing != null ) {
|
||||||
LOG.debugf(
|
LOG.debugf(
|
||||||
"Skipping registration of BasicType (%s + %s); still priming. existing = %s",
|
"Skipping registration of BasicType (%s + %s); still priming. existing = %s",
|
||||||
type.getJdbcType().getFriendlyName(),
|
jdbcType.getFriendlyName(),
|
||||||
type.getJavaTypeDescriptor(),
|
type.getJavaTypeDescriptor(),
|
||||||
existing
|
existing
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
typeByJavaTypeForJdbcType.put( type.getMappedJavaType(), type );
|
registryForJdbcType( jdbcType ).put( type.getMappedJavaType(), type );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<JavaType<?>, BasicType<?>> registryForJdbcType(JdbcType jdbcType) {
|
||||||
|
return registryValues.computeIfAbsent( jdbcType, key -> new ConcurrentHashMap<>() );
|
||||||
|
}
|
||||||
|
|
||||||
private void applyRegistrationKeys(BasicType<?> type, String[] keys) {
|
private void applyRegistrationKeys(BasicType<?> type, String[] keys) {
|
||||||
for ( String key : keys ) {
|
for ( String key : keys ) {
|
||||||
// be safe...
|
// be safe...
|
||||||
|
|
|
@ -19,7 +19,7 @@ import org.hibernate.type.spi.TypeConfiguration;
|
||||||
* Descriptor for a basic plural Java type.
|
* Descriptor for a basic plural Java type.
|
||||||
* A basic plural type represents a type, that is mapped to a single column instead of multiple rows.
|
* A basic plural type represents a type, that is mapped to a single column instead of multiple rows.
|
||||||
* This is used for array or collection types, that are backed by e.g. SQL array or JSON/XML DDL types.
|
* This is used for array or collection types, that are backed by e.g. SQL array or JSON/XML DDL types.
|
||||||
*
|
* <p>
|
||||||
* The interface can be implemented by a plural java type e.g. {@link org.hibernate.type.descriptor.java.spi.BasicCollectionJavaType}
|
* The interface can be implemented by a plural java type e.g. {@link org.hibernate.type.descriptor.java.spi.BasicCollectionJavaType}
|
||||||
* and provides access to the element java type, as well as a hook to resolve the {@link BasicType} based on the element {@link BasicType},
|
* and provides access to the element java type, as well as a hook to resolve the {@link BasicType} based on the element {@link BasicType},
|
||||||
* in order to gain enough information to implement storage and retrieval of the composite data type via JDBC.
|
* in order to gain enough information to implement storage and retrieval of the composite data type via JDBC.
|
||||||
|
|
|
@ -387,8 +387,7 @@ public class BasicCollectionJavaType<C extends Collection<E>, E> extends Abstrac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( value instanceof Object[] ) {
|
if ( value instanceof Object[] raw ) {
|
||||||
final Object[] raw = (Object[]) value;
|
|
||||||
final C wrapped = semantics.instantiateRaw( raw.length, null );
|
final C wrapped = semantics.instantiateRaw( raw.length, null );
|
||||||
if ( componentJavaType.getJavaTypeClass().isAssignableFrom( value.getClass().getComponentType() ) ) {
|
if ( componentJavaType.getJavaTypeClass().isAssignableFrom( value.getClass().getComponentType() ) ) {
|
||||||
for ( Object o : raw ) {
|
for ( Object o : raw ) {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.type.spi;
|
package org.hibernate.type.spi;
|
||||||
|
|
||||||
import java.io.InvalidObjectException;
|
import java.io.InvalidObjectException;
|
||||||
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
@ -32,6 +33,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.Incubating;
|
import org.hibernate.Incubating;
|
||||||
import org.hibernate.Internal;
|
import org.hibernate.Internal;
|
||||||
|
@ -499,7 +501,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
||||||
return sessionFactory.getServiceRegistry();
|
return sessionFactory.getServiceRegistry();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return null;
|
throw new AssertionFailure( "No service registry available" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,6 +576,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// Custom serialization hook
|
// Custom serialization hook
|
||||||
|
|
||||||
|
@Serial
|
||||||
private Object readResolve() throws InvalidObjectException {
|
private Object readResolve() throws InvalidObjectException {
|
||||||
if ( sessionFactory == null ) {
|
if ( sessionFactory == null ) {
|
||||||
if ( sessionFactoryName != null || sessionFactoryUuid != null ) {
|
if ( sessionFactoryName != null || sessionFactoryUuid != null ) {
|
||||||
|
@ -633,7 +636,8 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
return Arrays.equals( components, ((ArrayCacheKey) o).components );
|
return o instanceof ArrayCacheKey key
|
||||||
|
&& Arrays.equals( components, key.components );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -799,6 +803,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public TemporalType getSqlTemporalType(SqmExpressible<?> type) {
|
public TemporalType getSqlTemporalType(SqmExpressible<?> type) {
|
||||||
if ( type == null ) {
|
if ( type == null ) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -806,15 +811,18 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
||||||
return getSqlTemporalType( type.getRelationalJavaType().getRecommendedJdbcType( getCurrentBaseSqlTypeIndicators() ) );
|
return getSqlTemporalType( type.getRelationalJavaType().getRecommendedJdbcType( getCurrentBaseSqlTypeIndicators() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public static TemporalType getSqlTemporalType(JdbcMapping jdbcMapping) {
|
public static TemporalType getSqlTemporalType(JdbcMapping jdbcMapping) {
|
||||||
return getSqlTemporalType( jdbcMapping.getJdbcType() );
|
return getSqlTemporalType( jdbcMapping.getJdbcType() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public static TemporalType getSqlTemporalType(JdbcMappingContainer jdbcMappings) {
|
public static TemporalType getSqlTemporalType(JdbcMappingContainer jdbcMappings) {
|
||||||
assert jdbcMappings.getJdbcTypeCount() == 1;
|
assert jdbcMappings.getJdbcTypeCount() == 1;
|
||||||
return getSqlTemporalType( jdbcMappings.getSingleJdbcMapping().getJdbcType() );
|
return getSqlTemporalType( jdbcMappings.getSingleJdbcMapping().getJdbcType() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public static TemporalType getSqlTemporalType(MappingModelExpressible<?> type) {
|
public static TemporalType getSqlTemporalType(MappingModelExpressible<?> type) {
|
||||||
if ( type instanceof BasicValuedMapping basicValuedMapping ) {
|
if ( type instanceof BasicValuedMapping basicValuedMapping ) {
|
||||||
return getSqlTemporalType( basicValuedMapping.getJdbcMapping().getJdbcType() );
|
return getSqlTemporalType( basicValuedMapping.getJdbcMapping().getJdbcType() );
|
||||||
|
@ -838,25 +846,22 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public static TemporalType getSqlTemporalType(JdbcType descriptor) {
|
public static TemporalType getSqlTemporalType(JdbcType descriptor) {
|
||||||
return getSqlTemporalType( descriptor.getDefaultSqlTypeCode() );
|
return getSqlTemporalType( descriptor.getDefaultSqlTypeCode() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
protected static TemporalType getSqlTemporalType(int jdbcTypeCode) {
|
protected static TemporalType getSqlTemporalType(int jdbcTypeCode) {
|
||||||
switch ( jdbcTypeCode ) {
|
return switch ( jdbcTypeCode ) {
|
||||||
case SqlTypes.TIMESTAMP:
|
case SqlTypes.TIMESTAMP, SqlTypes.TIMESTAMP_WITH_TIMEZONE, SqlTypes.TIMESTAMP_UTC
|
||||||
case SqlTypes.TIMESTAMP_WITH_TIMEZONE:
|
-> TemporalType.TIMESTAMP;
|
||||||
case SqlTypes.TIMESTAMP_UTC:
|
case SqlTypes.TIME, SqlTypes.TIME_WITH_TIMEZONE, SqlTypes.TIME_UTC
|
||||||
return TemporalType.TIMESTAMP;
|
-> TemporalType.TIME;
|
||||||
case SqlTypes.TIME:
|
case SqlTypes.DATE
|
||||||
case SqlTypes.TIME_WITH_TIMEZONE:
|
-> TemporalType.DATE;
|
||||||
case SqlTypes.TIME_UTC:
|
default -> null;
|
||||||
return TemporalType.TIME;
|
};
|
||||||
case SqlTypes.DATE:
|
|
||||||
return TemporalType.DATE;
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IntervalType getSqlIntervalType(JdbcMappingContainer jdbcMappings) {
|
public static IntervalType getSqlIntervalType(JdbcMappingContainer jdbcMappings) {
|
||||||
|
@ -869,12 +874,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static IntervalType getSqlIntervalType(int jdbcTypeCode) {
|
protected static IntervalType getSqlIntervalType(int jdbcTypeCode) {
|
||||||
switch ( jdbcTypeCode ) {
|
return jdbcTypeCode == SqlTypes.INTERVAL_SECOND ? IntervalType.SECOND : null;
|
||||||
case SqlTypes.INTERVAL_SECOND:
|
|
||||||
return IntervalType.SECOND;
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isJdbcTemporalType(SqmExpressible<?> type) {
|
public static boolean isJdbcTemporalType(SqmExpressible<?> type) {
|
||||||
|
|
Loading…
Reference in New Issue