Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HHH-18532 Date/time related JavaType's are not always properly unwrapping into java.util.Date subclasses #8833

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
*/
package org.hibernate.type.descriptor.java;

import java.sql.Time;
import java.time.Instant;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Comparator;

import jakarta.persistence.TemporalType;
Expand Down Expand Up @@ -60,6 +64,13 @@ private <X> TemporalJavaType<X> forMissingPrecision(TypeConfiguration typeConfig
return (TemporalJavaType) this;
}

public static Time millisToSqlTime(long millis) {
final LocalTime localTime = Instant.ofEpochMilli( millis ).atZone( ZoneId.systemDefault() ).toLocalTime();
final Time time = Time.valueOf( localTime );
time.setTime( time.getTime() + localTime.getNano() / 1_000_000 );
return time;
}

protected <X> TemporalJavaType<X> forTimestampPrecision(TypeConfiguration typeConfiguration) {
throw new UnsupportedOperationException(
this + " as `jakarta.persistence.TemporalType.TIMESTAMP` not supported"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public <X> X unwrap(Calendar value, Class<X> type, WrapperOptions options) {
return (X) new java.sql.Date( value.getTimeInMillis() );
}
if ( java.sql.Time.class.isAssignableFrom( type ) ) {
return (X) new java.sql.Time( value.getTimeInMillis() % 86_400_000 );
return (X) millisToSqlTime( value.getTimeInMillis() );
}
if ( java.sql.Timestamp.class.isAssignableFrom( type ) ) {
return (X) new java.sql.Timestamp( value.getTimeInMillis() );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public <X> X unwrap(Calendar value, Class<X> type, WrapperOptions options) {
return (X) new java.sql.Date( value.getTimeInMillis() );
}
if ( java.sql.Time.class.isAssignableFrom( type ) ) {
return (X) new java.sql.Time( value.getTimeInMillis() % 86_400_000 );
return (X) millisToSqlTime( value.getTimeInMillis() );
}
if ( java.sql.Timestamp.class.isAssignableFrom( type ) ) {
return (X) new java.sql.Timestamp( value.getTimeInMillis() );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public <X> X unwrap(Calendar value, Class<X> type, WrapperOptions options) {
return (X) new java.sql.Date( value.getTimeInMillis() );
}
if ( java.sql.Time.class.isAssignableFrom( type ) ) {
return (X) new java.sql.Time( value.getTimeInMillis() % 86_400_000 );
return (X) millisToSqlTime( value.getTimeInMillis() );
}
if ( java.sql.Timestamp.class.isAssignableFrom( type ) ) {
return (X) new java.sql.Timestamp( value.getTimeInMillis() );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public <X> X unwrap(Date value, Class<X> type, WrapperOptions options) {
if ( java.sql.Time.class.isAssignableFrom( type ) ) {
final java.sql.Time rtn = value instanceof java.sql.Time
? ( java.sql.Time ) value
: new java.sql.Time( value.getTime() % 86_400_000 );
: millisToSqlTime( value.getTime() );
return (X) rtn;
}
if ( java.sql.Timestamp.class.isAssignableFrom( type ) ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public <X> X unwrap(Instant instant, Class<X> type, WrapperOptions options) {
}

if ( java.sql.Time.class.isAssignableFrom( type ) ) {
return (X) new java.sql.Time( instant.toEpochMilli() % 86_400_000 );
return (X) millisToSqlTime( instant.toEpochMilli() );
}

if ( Date.class.isAssignableFrom( type ) ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ public Object unwrap(Date value, Class type, WrapperOptions options) {
return unwrapSqlDate( value );
}

if ( java.sql.Timestamp.class.isAssignableFrom( type ) ) {
return new java.sql.Timestamp( unwrapDateEpoch( value ) );
}

if ( java.sql.Time.class.isAssignableFrom( type ) ) {
throw new IllegalArgumentException( "Illegal attempt to treat `java.sql.Date` as `java.sql.Time`" );
}

if ( java.util.Date.class.isAssignableFrom( type ) ) {
return value;
}
Expand All @@ -141,14 +149,6 @@ public Object unwrap(Date value, Class type, WrapperOptions options) {
return cal;
}

if ( java.sql.Timestamp.class.isAssignableFrom( type ) ) {
return new java.sql.Timestamp( unwrapDateEpoch( value ) );
}

if ( java.sql.Time.class.isAssignableFrom( type ) ) {
throw new IllegalArgumentException( "Illegal attempt to treat `java.sql.Date` as `java.sql.Time`" );
}

throw unknownUnwrap( type );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public Object unwrap(Date value, Class type, WrapperOptions options) {
if ( LocalTime.class.isAssignableFrom( type ) ) {
final Time time = value instanceof java.sql.Time
? ( (java.sql.Time) value )
: new java.sql.Time( value.getTime() % 86_400_000 );
: millisToSqlTime( value.getTime() );
final LocalTime localTime = time.toLocalTime();
long millis = time.getTime() % 1000;
if ( millis == 0 ) {
Expand All @@ -135,9 +135,15 @@ public Object unwrap(Date value, Class type, WrapperOptions options) {
}

if ( Time.class.isAssignableFrom( type ) ) {
return value instanceof Time
? value
: new Time( value.getTime() % 86_400_000 );
return millisToSqlTime( value.getTime() );
}

if ( java.sql.Timestamp.class.isAssignableFrom( type ) ) {
return new java.sql.Timestamp( value.getTime() );
}

if ( java.sql.Date.class.isAssignableFrom( type ) ) {
throw new IllegalArgumentException( "Illegal attempt to treat `java.sql.Time` as `java.sql.Date`" );
}

if ( Date.class.isAssignableFrom( type ) ) {
Expand All @@ -158,14 +164,6 @@ public Object unwrap(Date value, Class type, WrapperOptions options) {
return cal;
}

if ( java.sql.Timestamp.class.isAssignableFrom( type ) ) {
return new java.sql.Timestamp( value.getTime() );
}

if ( java.sql.Date.class.isAssignableFrom( type ) ) {
throw new IllegalArgumentException( "Illegal attempt to treat `java.sql.Time` as `java.sql.Date`" );
}

throw unknownUnwrap( type );
}

Expand All @@ -175,12 +173,8 @@ public Date wrap(Object value, WrapperOptions options) {
return null;
}

if ( value instanceof Time time ) {
return time;
}

if ( value instanceof Date date ) {
return new Time( date.getTime() % 86_400_000 );
return millisToSqlTime( date.getTime() );
}

if ( value instanceof LocalTime localTime ) {
Expand All @@ -197,7 +191,7 @@ public Date wrap(Object value, WrapperOptions options) {
}

if ( value instanceof Calendar calendar ) {
return new Time( calendar.getTimeInMillis() % 86_400_000 );
return millisToSqlTime( calendar.getTimeInMillis() );
}

throw unknownWrap( value.getClass() );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,18 @@ public Object unwrap(Date value, Class type, WrapperOptions options) {
: new Timestamp( value.getTime() );
}

if ( java.sql.Date.class.isAssignableFrom( type ) ) {
return value instanceof java.sql.Date
? ( java.sql.Date ) value
: new java.sql.Date( value.getTime() );
}

if ( java.sql.Time.class.isAssignableFrom( type ) ) {
return value instanceof java.sql.Time
? ( java.sql.Time ) value
: millisToSqlTime( value.getTime() );
}

if ( Date.class.isAssignableFrom( type ) ) {
return value;
}
Expand All @@ -146,18 +158,6 @@ public Object unwrap(Date value, Class type, WrapperOptions options) {
return value.getTime();
}

if ( java.sql.Date.class.isAssignableFrom( type ) ) {
return value instanceof java.sql.Date
? ( java.sql.Date ) value
: new java.sql.Date( value.getTime() );
}

if ( java.sql.Time.class.isAssignableFrom( type ) ) {
return value instanceof java.sql.Time
? ( java.sql.Time ) value
: new java.sql.Time( value.getTime() % 86_400_000 );
}

throw unknownUnwrap( type );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,12 @@ public <X> X unwrap(LocalDateTime value, Class<X> type, WrapperOptions options)

if ( java.sql.Date.class.isAssignableFrom( type ) ) {
Instant instant = value.atZone( ZoneId.systemDefault() ).toInstant();
return (X) java.sql.Date.from( instant );
return (X) new java.sql.Date( instant.toEpochMilli() );
}

if ( java.sql.Time.class.isAssignableFrom( type ) ) {
Instant instant = value.atZone( ZoneId.systemDefault() ).toInstant();
return (X) java.sql.Time.from( instant );
return (X) millisToSqlTime( instant.toEpochMilli() );
}

if ( Date.class.isAssignableFrom( type ) ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,11 @@ public <X> X unwrap(OffsetDateTime offsetDateTime, Class<X> type, WrapperOptions
}

if ( java.sql.Date.class.isAssignableFrom( type ) ) {
return (X) java.sql.Date.from( offsetDateTime.toInstant() );
return (X) new java.sql.Date( offsetDateTime.toInstant().toEpochMilli() );
}

if ( java.sql.Time.class.isAssignableFrom( type ) ) {
return (X) java.sql.Time.from( offsetDateTime.toInstant() );
return (X) millisToSqlTime( offsetDateTime.toInstant().toEpochMilli() );
}

if ( Date.class.isAssignableFrom( type ) ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ public <X> X unwrap(OffsetTime offsetTime, Class<X> type, WrapperOptions options
return (X) Long.valueOf( instant.toEpochMilli() );
}

if ( java.sql.Date.class.isAssignableFrom( type ) ) {
throw new IllegalArgumentException( "Illegal attempt to treat `java.time.OffsetTime` as `java.sql.Date`" );
}

if ( Date.class.isAssignableFrom( type ) ) {
return (X) Date.from( instant );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,11 @@ public <X> X unwrap(ZonedDateTime zonedDateTime, Class<X> type, WrapperOptions o
}

if ( java.sql.Date.class.isAssignableFrom( type ) ) {
return (X) java.sql.Date.from( zonedDateTime.toInstant() );
return (X) new java.sql.Date( zonedDateTime.toInstant().toEpochMilli() );
}

if ( java.sql.Time.class.isAssignableFrom( type ) ) {
return (X) java.sql.Time.from( zonedDateTime.toInstant() );
return (X) millisToSqlTime( zonedDateTime.toInstant().toEpochMilli() );
}

if ( Date.class.isAssignableFrom( type ) ) {
Expand Down
Loading