4040import org .hibernate .engine .jdbc .Size ;
4141import org .hibernate .internal .CoreLogging ;
4242import org .hibernate .internal .CoreMessageLogger ;
43- import org .hibernate .internal .util .ReflectHelper ;
4443import org .hibernate .internal .util .StringHelper ;
4544import org .hibernate .internal .util .collections .CollectionHelper ;
4645import org .hibernate .metamodel .mapping .JdbcMapping ;
8281import jakarta .persistence .TemporalType ;
8382
8483import static java .lang .Boolean .parseBoolean ;
84+ import static org .hibernate .internal .util .ReflectHelper .reflectedPropertyType ;
8585import static org .hibernate .internal .util .collections .CollectionHelper .isNotEmpty ;
8686import static org .hibernate .mapping .MappingHelper .injectParameters ;
8787
@@ -103,6 +103,7 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
103103 private Function <TypeConfiguration , java .lang .reflect .Type > implicitJavaTypeAccess ;
104104
105105 private EnumType enumerationStyle ;
106+ @ SuppressWarnings ("deprecation" )
106107 private TemporalType temporalPrecision ;
107108 private TimeZoneStorageType timeZoneStorageType ;
108109 private boolean isSoftDelete ;
@@ -234,8 +235,7 @@ public java.lang.reflect.Type getResolvedJavaType() {
234235 public long getColumnLength () {
235236 final Selectable selectable = getColumn ();
236237 if ( selectable instanceof Column ) {
237- final Column column = (Column ) selectable ;
238- final Long length = column .getLength ();
238+ final Long length = ( (Column ) selectable ).getLength ();
239239 return length == null ? NO_COLUMN_LENGTH : length ;
240240 }
241241 else {
@@ -248,8 +248,9 @@ public int getColumnPrecision() {
248248 final Selectable selectable = getColumn ();
249249 if ( selectable instanceof Column ) {
250250 final Column column = (Column ) selectable ;
251- if ( column .getTemporalPrecision () != null ) {
252- return column .getTemporalPrecision ();
251+ final Integer temporalPrecision = column .getTemporalPrecision ();
252+ if ( temporalPrecision != null ) {
253+ return temporalPrecision ;
253254 }
254255 final Integer precision = column .getPrecision ();
255256 return precision == null ? NO_COLUMN_PRECISION : precision ;
@@ -263,8 +264,7 @@ public int getColumnPrecision() {
263264 public int getColumnScale () {
264265 final Selectable selectable = getColumn ();
265266 if ( selectable instanceof Column ) {
266- final Column column = (Column ) selectable ;
267- final Integer scale = column .getScale ();
267+ final Integer scale = ( (Column ) selectable ).getScale ();
268268 return scale == null ? NO_COLUMN_SCALE : scale ;
269269 }
270270 else {
@@ -284,8 +284,9 @@ public void copyTypeFrom(SimpleValue sourceValue) {
284284 super .copyTypeFrom ( sourceValue );
285285 if ( sourceValue instanceof BasicValue ) {
286286 final BasicValue basicValue = (BasicValue ) sourceValue ;
287- this .resolution = basicValue .resolution ;
288- this .implicitJavaTypeAccess = (typeConfiguration ) -> basicValue .implicitJavaTypeAccess .apply ( typeConfiguration );
287+ resolution = basicValue .resolution ;
288+ implicitJavaTypeAccess =
289+ typeConfiguration -> basicValue .implicitJavaTypeAccess .apply ( typeConfiguration );
289290 }
290291 }
291292
@@ -447,55 +448,71 @@ && parseBoolean( typeParameters.getProperty(DynamicParameterizedType.IS_DYNAMIC)
447448 getBuildingContext ()
448449 );
449450 }
450-
451- if ( isVersion () ) {
451+ else if ( isVersion () ) {
452452 return VersionResolution .from ( implicitJavaTypeAccess , timeZoneStorageType , getBuildingContext () );
453453 }
454+ else {
455+ // determine JavaType if we can
456+ final BasicJavaType <?> explicitJavaType = getExplicitJavaType ();
457+ final JavaType <?> javaType = determineJavaType ( explicitJavaType );
458+ final ConverterDescriptor converterDescriptor = getConverterDescriptor ( javaType );
459+ return converterDescriptor != null
460+ ? converterResolution ( javaType , converterDescriptor )
461+ : resolution ( explicitJavaType , javaType );
462+ }
463+ }
454464
455- // determine JavaType if we can
456- final BasicJavaType <?> explicitJavaType = explicitJavaTypeAccess == null
457- ? null
465+ private BasicJavaType <?> getExplicitJavaType () {
466+ return explicitJavaTypeAccess == null ? null
458467 : explicitJavaTypeAccess .apply ( getTypeConfiguration () );
468+ }
459469
460- JavaType <?> javaType = determineJavaType ( explicitJavaType );
461- ConverterDescriptor attributeConverterDescriptor = getAttributeConverterDescriptor ();
462-
470+ private ConverterDescriptor getConverterDescriptor (JavaType <?> javaType ) {
471+ final ConverterDescriptor converterDescriptor = getAttributeConverterDescriptor ();
463472 if ( isSoftDelete () ) {
464- assert attributeConverterDescriptor != null ;
465- final boolean conversionWasUnspecified = SoftDelete .UnspecifiedConversion .class .equals ( attributeConverterDescriptor .getAttributeConverterClass () );
466- if ( conversionWasUnspecified ) {
467- final JdbcType jdbcType = BooleanJdbcType .INSTANCE .resolveIndicatedType ( this , javaType );
468- if ( jdbcType .isNumber () ) {
469- attributeConverterDescriptor = new InstanceBasedConverterDescriptor (
470- NumericBooleanConverter .INSTANCE ,
471- getBuildingContext ().getBootstrapContext ().getClassmateContext ()
472- );
473- }
474- else if ( jdbcType .isString () ) {
475- // here we pick 'T' / 'F' storage, though 'Y' / 'N' is equally valid - its 50/50
476- attributeConverterDescriptor = new InstanceBasedConverterDescriptor (
477- TrueFalseConverter .INSTANCE ,
478- getBuildingContext ().getBootstrapContext ().getClassmateContext ()
479- );
480- }
481- else {
482- // should indicate BIT or BOOLEAN == no conversion needed
483- // - we still create the converter to properly set up JDBC type, etc
484- attributeConverterDescriptor = new InstanceBasedConverterDescriptor (
485- PassThruSoftDeleteConverter .INSTANCE ,
486- getBuildingContext ().getBootstrapContext ().getClassmateContext ()
487- );
488- }
489- }
473+ assert converterDescriptor != null ;
474+ final ConverterDescriptor softDeleteConverterDescriptor =
475+ getSoftDeleteConverterDescriptor ( converterDescriptor , javaType );
476+ return getSoftDeleteStrategy () == SoftDeleteType .ACTIVE
477+ ? new ReversedConverterDescriptor <>( softDeleteConverterDescriptor )
478+ : softDeleteConverterDescriptor ;
479+ }
480+ else {
481+ return converterDescriptor ;
482+ }
483+ }
490484
491- if ( getSoftDeleteStrategy () == SoftDeleteType .ACTIVE ) {
492- attributeConverterDescriptor = new ReversedConverterDescriptor <>( attributeConverterDescriptor );
485+ private ConverterDescriptor getSoftDeleteConverterDescriptor (
486+ ConverterDescriptor attributeConverterDescriptor , JavaType <?> javaType ) {
487+ final boolean conversionWasUnspecified =
488+ SoftDelete .UnspecifiedConversion .class .equals ( attributeConverterDescriptor .getAttributeConverterClass () );
489+ if ( conversionWasUnspecified ) {
490+ final JdbcType jdbcType = BooleanJdbcType .INSTANCE .resolveIndicatedType ( this , javaType );
491+ if ( jdbcType .isNumber () ) {
492+ return new InstanceBasedConverterDescriptor (
493+ NumericBooleanConverter .INSTANCE ,
494+ getBuildingContext ().getBootstrapContext ().getClassmateContext ()
495+ );
496+ }
497+ else if ( jdbcType .isString () ) {
498+ // here we pick 'T' / 'F' storage, though 'Y' / 'N' is equally valid - its 50/50
499+ return new InstanceBasedConverterDescriptor (
500+ TrueFalseConverter .INSTANCE ,
501+ getBuildingContext ().getBootstrapContext ().getClassmateContext ()
502+ );
503+ }
504+ else {
505+ // should indicate BIT or BOOLEAN == no conversion needed
506+ // - we still create the converter to properly set up JDBC type, etc
507+ return new InstanceBasedConverterDescriptor (
508+ PassThruSoftDeleteConverter .INSTANCE ,
509+ getBuildingContext ().getBootstrapContext ().getClassmateContext ()
510+ );
493511 }
494512 }
495-
496- return attributeConverterDescriptor != null
497- ? converterResolution ( javaType , attributeConverterDescriptor )
498- : resolution ( explicitJavaType , javaType );
513+ else {
514+ return attributeConverterDescriptor ;
515+ }
499516 }
500517
501518 private static class ReversedConverterDescriptor <R > implements ConverterDescriptor {
@@ -680,11 +697,10 @@ private Resolution<?> converterResolution(JavaType<?> javaType, ConverterDescrip
680697 && !attributeConverterDescriptor .getDomainValueResolvedType ().getErasedType ()
681698 .isAssignableFrom ( javaType .getJavaTypeClass () ) ) {
682699 // In this case, the converter applies to the element of a BasicPluralJavaType
683- final BasicPluralJavaType <?> containerJtd = (BasicPluralJavaType <?>) javaType ;
684700 final BasicType registeredElementType = converterResolution .getLegacyResolvedBasicType ();
685701 final Selectable column = getColumn ();
686702 final BasicType <?> registeredType = registeredElementType == null ? null
687- : containerJtd .resolveType (
703+ : ( ( BasicPluralJavaType <?>) javaType ) .resolveType (
688704 getTypeConfiguration (),
689705 getDialect (),
690706 registeredElementType ,
@@ -730,66 +746,76 @@ private JavaType<?> determineJavaType(JavaType<?> explicitJavaType) {
730746 }
731747
732748 private JavaType <?> determineReflectedJavaType () {
733- final java .lang .reflect .Type impliedJavaType ;
734-
735749 final TypeConfiguration typeConfiguration = getTypeConfiguration ();
750+ final java .lang .reflect .Type impliedJavaType = impliedJavaType ( typeConfiguration );
751+ if ( impliedJavaType == null ) {
752+ return null ;
753+ }
754+ else {
755+ resolvedJavaType = impliedJavaType ;
756+ return javaType ( typeConfiguration , impliedJavaType );
757+ }
758+ }
759+
760+ private java .lang .reflect .Type impliedJavaType (TypeConfiguration typeConfiguration ) {
736761 if ( resolvedJavaType != null ) {
737- impliedJavaType = resolvedJavaType ;
762+ return resolvedJavaType ;
738763 }
739764 else if ( implicitJavaTypeAccess != null ) {
740- impliedJavaType = implicitJavaTypeAccess .apply ( typeConfiguration );
765+ return implicitJavaTypeAccess .apply (typeConfiguration );
741766 }
742767 else if ( ownerName != null && propertyName != null ) {
743- impliedJavaType = ReflectHelper .reflectedPropertyType (
744- ownerName ,
745- propertyName ,
746- getServiceRegistry ().requireService ( ClassLoaderService .class )
747- );
768+ return reflectedPropertyType ( ownerName , propertyName ,
769+ getServiceRegistry ().requireService ( ClassLoaderService .class ) );
748770 }
749771 else {
750772 return null ;
751773 }
774+ }
752775
753- resolvedJavaType = impliedJavaType ;
776+ private JavaType <Object > javaType (TypeConfiguration typeConfiguration , java .lang .reflect .Type impliedJavaType ) {
777+ final JavaType <Object > javaType = typeConfiguration .getJavaTypeRegistry ().findDescriptor ( impliedJavaType );
778+ return javaType == null ? specialJavaType ( typeConfiguration , impliedJavaType ) : javaType ;
779+ }
754780
755- if ( impliedJavaType == null ) {
756- return null ;
781+ private JavaType <Object > specialJavaType (
782+ TypeConfiguration typeConfiguration ,
783+ java .lang .reflect .Type impliedJavaType ) {
784+ final JavaTypeRegistry javaTypeRegistry = typeConfiguration .getJavaTypeRegistry ();
785+ if ( jdbcTypeCode != null ) {
786+ // Construct special JavaType instances for JSON/XML types which can report recommended JDBC types
787+ // and implement toString/fromString as well as copying based on FormatMapper operations
788+ switch ( jdbcTypeCode ) {
789+ case SqlTypes .JSON :
790+ final JavaType <Object > jsonJavaType =
791+ new JsonJavaType <>( impliedJavaType ,
792+ mutabilityPlan ( typeConfiguration , impliedJavaType ),
793+ typeConfiguration );
794+ javaTypeRegistry .addDescriptor ( jsonJavaType );
795+ return jsonJavaType ;
796+ case SqlTypes .SQLXML :
797+ final JavaType <Object > xmlJavaType =
798+ new XmlJavaType <>( impliedJavaType ,
799+ mutabilityPlan ( typeConfiguration , impliedJavaType ),
800+ typeConfiguration );
801+ javaTypeRegistry .addDescriptor ( xmlJavaType );
802+ return xmlJavaType ;
803+ }
757804 }
805+ return javaTypeRegistry .resolveDescriptor ( impliedJavaType );
806+ }
758807
759- final JavaTypeRegistry javaTypeRegistry = typeConfiguration .getJavaTypeRegistry ();
760- final JavaType <Object > javaType = javaTypeRegistry .findDescriptor ( impliedJavaType );
761- final MutabilityPlan <Object > explicitMutabilityPlan = explicitMutabilityPlanAccess != null
762- ? explicitMutabilityPlanAccess .apply ( typeConfiguration )
763- : null ;
764- final MutabilityPlan <Object > determinedMutabilityPlan = explicitMutabilityPlan != null
808+ private MutabilityPlan <Object > mutabilityPlan (
809+ TypeConfiguration typeConfiguration , java .lang .reflect .Type impliedJavaType ) {
810+ final MutabilityPlan <Object > explicitMutabilityPlan = getExplicitMutabilityPlan ();
811+ return explicitMutabilityPlan != null
765812 ? explicitMutabilityPlan
766813 : RegistryHelper .INSTANCE .determineMutabilityPlan ( impliedJavaType , typeConfiguration );
767- if ( javaType == null ) {
768- if ( jdbcTypeCode != null ) {
769- // Construct special JavaType instances for JSON/XML types which can report recommended JDBC types
770- // and implement toString/fromString as well as copying based on FormatMapper operations
771- switch ( jdbcTypeCode ) {
772- case SqlTypes .JSON :
773- final JavaType <Object > jsonJavaType = new JsonJavaType <>(
774- impliedJavaType ,
775- determinedMutabilityPlan ,
776- typeConfiguration
777- );
778- javaTypeRegistry .addDescriptor ( jsonJavaType );
779- return jsonJavaType ;
780- case SqlTypes .SQLXML :
781- final JavaType <Object > xmlJavaType = new XmlJavaType <>(
782- impliedJavaType ,
783- determinedMutabilityPlan ,
784- typeConfiguration
785- );
786- javaTypeRegistry .addDescriptor ( xmlJavaType );
787- return xmlJavaType ;
788- }
789- }
790- return javaTypeRegistry .resolveDescriptor ( impliedJavaType );
791- }
792- return javaType ;
814+ }
815+
816+ private MutabilityPlan <Object > getExplicitMutabilityPlan () {
817+ return explicitMutabilityPlanAccess == null ? null
818+ : explicitMutabilityPlanAccess .apply ( getTypeConfiguration () );
793819 }
794820
795821 private static Resolution <?> interpretExplicitlyNamedType (
@@ -1066,8 +1092,7 @@ private UserType<?> getConfiguredUserTypeBean(Class<? extends UserType<?>> expli
10661092 : getUserTypeBean ( explicitCustomType , properties ).getBeanInstance ();
10671093
10681094 if ( typeInstance instanceof TypeConfigurationAware ) {
1069- final TypeConfigurationAware configurationAware = (TypeConfigurationAware ) typeInstance ;
1070- configurationAware .setTypeConfiguration ( getTypeConfiguration () );
1095+ ( (TypeConfigurationAware ) typeInstance ).setTypeConfiguration ( getTypeConfiguration () );
10711096 }
10721097
10731098 if ( typeInstance instanceof DynamicParameterizedType ) {
@@ -1097,11 +1122,12 @@ private <T> ManagedBean<T> getUserTypeBean(Class<T> explicitCustomType, Properti
10971122 }
10981123 }
10991124
1125+ @ SuppressWarnings ("deprecation" )
11001126 public void setTemporalPrecision (TemporalType temporalPrecision ) {
11011127 this .temporalPrecision = temporalPrecision ;
11021128 }
11031129
1104- @ Override
1130+ @ Override @ SuppressWarnings ( "deprecation" )
11051131 public TemporalType getTemporalPrecision () {
11061132 return temporalPrecision ;
11071133 }
0 commit comments