1919import org .hibernate .type .descriptor .jdbc .JdbcTypeIndicators ;
2020import org .hibernate .type .spi .TypeConfiguration ;
2121
22- import static org .hibernate .type .descriptor .java .JdbcDateJavaType .toDateEpoch ;
23-
2422/**
2523 * Descriptor for {@link Date} handling.
2624 *
@@ -54,9 +52,9 @@ else if ( value instanceof java.sql.Time time ) {
5452 }
5553 else {
5654 return switch ( precision ) {
57- case TIMESTAMP -> wrapSqlTimestamp ( value );
58- case DATE -> wrapSqlDate ( value );
59- case TIME -> wrapSqlTime ( value );
55+ case TIMESTAMP -> toTimestamp ( value );
56+ case DATE -> toDate ( value );
57+ case TIME -> toTime ( value );
6058 };
6159 }
6260 }
@@ -68,8 +66,13 @@ public DateJavaType() {
6866 this .precision = TemporalType .TIMESTAMP ;
6967 }
7068
69+ /**
70+ * A {@link Date} may be used to represent a date, time, or timestamp,
71+ * each of which have different semantics at the Java level. Therefore,
72+ * we distinguish these usages based on the given {@code TemporalType}.
73+ */
7174 private DateJavaType (@ SuppressWarnings ("deprecation" ) TemporalType precision ) {
72- super ( Date .class , new DateMutabilityPlan (precision ) );
75+ super ( Date .class , new DateMutabilityPlan ( precision ) );
7376 this .precision = precision ;
7477 }
7578
@@ -117,9 +120,9 @@ public JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) {
117120 public String toString (Date value ) {
118121// return JdbcTimestampJavaType.LITERAL_FORMATTER.format( value.toInstant() );
119122 return switch ( precision ) {
120- case TIMESTAMP -> JdbcTimestampJavaType .INSTANCE .toString ( wrapSqlTimestamp ( value ) );
121- case DATE -> JdbcDateJavaType .INSTANCE .toString ( wrapSqlDate ( value ) );
122- case TIME -> JdbcTimeJavaType .INSTANCE .toString ( wrapSqlTime ( value ) );
123+ case TIMESTAMP -> JdbcTimestampJavaType .INSTANCE .toString ( toTimestamp ( value ) );
124+ case DATE -> JdbcDateJavaType .INSTANCE .toString ( toDate ( value ) );
125+ case TIME -> JdbcTimeJavaType .INSTANCE .toString ( toTime ( value ) );
123126 };
124127 }
125128
@@ -130,16 +133,6 @@ public Date fromString(CharSequence string) {
130133 case DATE -> JdbcDateJavaType .INSTANCE .fromString ( string );
131134 case TIME -> JdbcTimeJavaType .INSTANCE .fromString ( string );
132135 };
133- // try {
134- // final var accessor = JdbcTimestampJavaType.LITERAL_FORMATTER.parse( string );
135- // return new Date(
136- // accessor.getLong( ChronoField.INSTANT_SECONDS ) * 1000L
137- // + accessor.get( ChronoField.NANO_OF_SECOND ) / 1_000_000
138- // );
139- // }
140- // catch ( DateTimeParseException pe) {
141- // throw new HibernateException( "could not parse timestamp string" + string, pe );
142- // }
143136 }
144137
145138 @ Override
@@ -149,9 +142,10 @@ public boolean areEqual(Date one, Date another) {
149142 }
150143 return one != null && another != null
151144 && switch ( precision ) {
152- case DATE -> JdbcDateJavaType .INSTANCE .areEqual ( wrapSqlDate ( one ), wrapSqlDate ( another ) );
153- case TIME -> JdbcTimeJavaType .INSTANCE .areEqual ( wrapSqlTime ( one ), wrapSqlTime ( another ) );
145+ case DATE -> JdbcDateJavaType .INSTANCE .areEqual ( toDate ( one ), toDate ( another ) );
146+ case TIME -> JdbcTimeJavaType .INSTANCE .areEqual ( toTime ( one ), toTime ( another ) );
154147 case TIMESTAMP ->
148+ // emulate legacy behavior (good or not)
155149 one instanceof Timestamp timestamp && another instanceof Timestamp anotherTimestamp
156150 ? JdbcTimestampJavaType .INSTANCE .areEqual ( timestamp , anotherTimestamp )
157151 : one .getTime () == another .getTime ();
@@ -182,9 +176,9 @@ public int extractHashCode(Date value) {
182176 @ Override
183177 public <X > X unwrap (Date value , Class <X > type , WrapperOptions options ) {
184178 return switch ( precision ) {
185- case TIMESTAMP -> JdbcTimestampJavaType .INSTANCE .unwrap ( wrapSqlTimestamp ( value ), type , options );
186- case DATE -> JdbcDateJavaType .INSTANCE .unwrap ( wrapSqlDate ( value ), type , options );
187- case TIME -> JdbcTimeJavaType .INSTANCE .unwrap ( wrapSqlTime ( value ), type , options );
179+ case TIMESTAMP -> JdbcTimestampJavaType .INSTANCE .unwrap ( toTimestamp ( value ), type , options );
180+ case DATE -> JdbcDateJavaType .INSTANCE .unwrap ( toDate ( value ), type , options );
181+ case TIME -> JdbcTimeJavaType .INSTANCE .unwrap ( toTime ( value ), type , options );
188182 };
189183 }
190184
@@ -228,23 +222,20 @@ public Date seed(
228222 return Timestamp .from ( ClockHelper .forPrecision ( precision , session ).instant () );
229223 }
230224
231- static Timestamp wrapSqlTimestamp (Date date ) {
232- return date instanceof Timestamp timestamp ? timestamp : new Timestamp ( date .getTime () );
225+ private static Timestamp toTimestamp (Date date ) {
226+ return date instanceof Timestamp timestamp
227+ ? timestamp
228+ : JdbcTimestampJavaType .wrapSqlTimestamp ( date );
233229 }
234230
235- static Time wrapSqlTime (Date date ) {
236- return date instanceof Time time ? time : new Time ( date .getTime () % 86_400_000 );
231+ private static Time toTime (Date date ) {
232+ return date instanceof Time time
233+ ? time
234+ : JdbcTimeJavaType .toTime ( date );
237235 }
238236
239- static java .sql .Date wrapSqlDate (java .util .Date value ) {
240- if ( value instanceof java .sql .Date date ) {
241- final long millis = date .getTime ();
242- final long dateEpoch = toDateEpoch ( millis );
243- return dateEpoch == millis ? date : new java .sql .Date ( dateEpoch );
244- }
245- else {
246- return new java .sql .Date ( toDateEpoch ( value ) );
247- }
237+ private static java .sql .Date toDate (java .util .Date value ) {
238+ return JdbcDateJavaType .toDate ( value );
248239 }
249240
250241}
0 commit comments