66
77import java .util .function .Supplier ;
88
9- import org .hibernate .MappingException ;
109import org .hibernate .engine .spi .IdentifierValue ;
1110import org .hibernate .engine .spi .VersionValue ;
1211import org .hibernate .mapping .KeyValue ;
12+ import org .hibernate .mapping .KeyValue .NullValueSemantic ;
1313import org .hibernate .property .access .spi .Getter ;
1414import org .hibernate .type .descriptor .java .JavaType ;
1515import org .hibernate .type .descriptor .java .VersionJavaType ;
@@ -35,28 +35,31 @@ public static IdentifierValue getUnsavedIdentifierValue(
3535 JavaType <?> idJavaType ,
3636 Getter getter ,
3737 Supplier <?> templateInstanceAccess ) {
38- final String unsavedValue = bootIdMapping .getNullValue ();
39- if ( unsavedValue == null ) {
40- if ( getter != null && templateInstanceAccess != null ) {
41- // use the id value of a newly instantiated instance as the unsaved-value
42- final Object defaultValue = getter .get ( templateInstanceAccess .get () );
43- return new IdentifierValue ( defaultValue );
44- }
45- else if ( idJavaType instanceof PrimitiveJavaType <?> primitiveJavaType ) {
46- return new IdentifierValue ( primitiveJavaType .getDefaultValue () );
47- }
48- else {
49- return IdentifierValue .NULL ;
50- }
38+ final NullValueSemantic nullValueSemantic = bootIdMapping .getNullValueSemantic ();
39+ return nullValueSemantic == null
40+ ? inferUnsavedIdentifierValue ( idJavaType , getter , templateInstanceAccess )
41+ : switch ( nullValueSemantic ) {
42+ case UNDEFINED -> IdentifierValue .UNDEFINED ;
43+ case NULL -> IdentifierValue .NULL ;
44+ case ANY -> IdentifierValue .ANY ;
45+ case NONE -> IdentifierValue .NONE ;
46+ case VALUE -> new IdentifierValue ( idJavaType .fromString ( bootIdMapping .getNullValue () ) );
47+ default -> throw new IllegalArgumentException ( "Illegal null-value semantic: " + nullValueSemantic );
48+ };
49+ }
50+
51+ private static IdentifierValue inferUnsavedIdentifierValue (
52+ JavaType <?> idJavaType , Getter getter , Supplier <?> templateInstanceAccess ) {
53+ if ( getter != null && templateInstanceAccess != null ) {
54+ // use the id value of a newly instantiated instance as the unsaved-value
55+ final Object defaultValue = getter .get ( templateInstanceAccess .get () );
56+ return new IdentifierValue ( defaultValue );
57+ }
58+ else if ( idJavaType instanceof PrimitiveJavaType <?> primitiveJavaType ) {
59+ return new IdentifierValue ( primitiveJavaType .getDefaultValue () );
5160 }
5261 else {
53- return switch ( unsavedValue ) {
54- case "null" -> IdentifierValue .NULL ;
55- case "undefined" -> IdentifierValue .UNDEFINED ;
56- case "none" -> IdentifierValue .NONE ;
57- case "any" -> IdentifierValue .ANY ;
58- default -> new IdentifierValue ( idJavaType .fromString ( unsavedValue ) );
59- };
62+ return IdentifierValue .NULL ;
6063 }
6164 }
6265
@@ -72,31 +75,33 @@ public static <T> VersionValue getUnsavedVersionValue(
7275 VersionJavaType <T > versionJavaType ,
7376 Getter getter ,
7477 Supplier <?> templateInstanceAccess ) {
75- final String unsavedValue = bootVersionMapping .getNullValue ();
76- if ( unsavedValue == null ) {
77- if ( getter != null && templateInstanceAccess != null ) {
78- final Object defaultValue = getter .get ( templateInstanceAccess .get () );
79- // if the version of a newly instantiated object is null
80- // or a negative number, use that value as the unsaved-value,
81- // otherwise assume it's the initial version set by program
82- return isNullInitialVersion ( defaultValue )
83- ? new VersionValue ( defaultValue )
84- : VersionValue .UNDEFINED ;
85- }
86- else {
87- return VersionValue .UNDEFINED ;
88- }
78+ final NullValueSemantic nullValueSemantic = bootVersionMapping .getNullValueSemantic ();
79+ return nullValueSemantic == null
80+ ? inferUnsavedVersionValue ( versionJavaType , getter , templateInstanceAccess )
81+ : switch ( nullValueSemantic ) {
82+ case UNDEFINED -> VersionValue .UNDEFINED ;
83+ case NULL -> VersionValue .NULL ;
84+ case NEGATIVE -> VersionValue .NEGATIVE ;
85+ // this should not happen since the DTD prevents it
86+ case VALUE -> new VersionValue ( versionJavaType .fromString ( bootVersionMapping .getNullValue () ) );
87+ default -> throw new IllegalArgumentException ( "Illegal null-value semantic: " + nullValueSemantic );
88+ };
89+ }
90+
91+ private static VersionValue inferUnsavedVersionValue (
92+ VersionJavaType <?> versionJavaType , Getter getter , Supplier <?> templateInstanceAccess ) {
93+ if ( getter != null && templateInstanceAccess != null ) {
94+ final Object defaultValue = getter .get ( templateInstanceAccess .get () );
95+ // if the version of a newly instantiated object is null
96+ // or a negative number, use that value as the unsaved-value,
97+ // otherwise assume it's the initial version set by program
98+ return isNullInitialVersion ( defaultValue )
99+ ? new VersionValue ( defaultValue )
100+ : VersionValue .UNDEFINED ;
89101 }
90102 else {
91- // this should not happen since the DTD prevents it
92- return switch ( unsavedValue ) {
93- case "undefined" -> VersionValue .UNDEFINED ;
94- case "null" -> VersionValue .NULL ;
95- case "negative" -> VersionValue .NEGATIVE ;
96- default -> throw new MappingException ( "Could not parse version unsaved-value: " + unsavedValue );
97- };
103+ return VersionValue .UNDEFINED ;
98104 }
99-
100105 }
101106
102107 private UnsavedValueFactory () {
0 commit comments