Skip to content

Commit

Permalink
HHH-18532 Suggested fix to conversion of epoch time in milliseconds t…
Browse files Browse the repository at this point in the history
…o java.sql.Time
  • Loading branch information
cigaly committed Nov 4, 2024
1 parent bdb52c6 commit e5a3870
Show file tree
Hide file tree
Showing 13 changed files with 31 additions and 32 deletions.
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 @@ -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,7 @@ 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 ) ) {
Expand Down Expand Up @@ -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 @@ -137,7 +137,7 @@ public Object unwrap(Date value, Class type, WrapperOptions options) {
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 );
: millisToSqlTime( value.getTime() );
}

if ( Date.class.isAssignableFrom( type ) ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public <X> X unwrap(LocalDateTime value, Class<X> type, WrapperOptions options)

if ( java.sql.Time.class.isAssignableFrom( type ) ) {
Instant instant = value.atZone( ZoneId.systemDefault() ).toInstant();
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 @@ -157,7 +157,7 @@ public <X> X unwrap(OffsetDateTime offsetDateTime, Class<X> type, WrapperOptions
}

if ( java.sql.Time.class.isAssignableFrom( type ) ) {
return (X) new java.sql.Time( offsetDateTime.toInstant().toEpochMilli() % 86_400_000 );
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 @@ -124,7 +124,7 @@ public <X> X unwrap(ZonedDateTime zonedDateTime, Class<X> type, WrapperOptions o
}

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

if ( Date.class.isAssignableFrom( type ) ) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.mapping.type.java;

Expand All @@ -17,15 +15,8 @@
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NonContextualLobCreator;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.CalendarDateJavaType;
import org.hibernate.type.descriptor.java.CalendarJavaType;
Expand Down Expand Up @@ -173,7 +164,7 @@ void testOffsetTimeJavaType(SessionFactoryScope scope) {

assertInstanceOf( Timestamp.class, javaType.unwrap( time, Timestamp.class, wrapperOptions ) );
assertThrows( IllegalArgumentException.class,
() -> javaType.unwrap( time, java.sql.Date.class, wrapperOptions ) );
() -> javaType.unwrap( time, java.sql.Date.class, wrapperOptions ) );
assertInstanceOf( Time.class, javaType.unwrap( time, Time.class, wrapperOptions ) );
assertInstanceOf( Date.class, javaType.unwrap( time, Date.class, wrapperOptions ) );
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.mapping.type.java;

import java.sql.Time;
Expand Down Expand Up @@ -43,7 +47,6 @@
@DomainModel(annotatedClasses = GoodBadUglyTest.Times.class)
@SessionFactory
@SkipForDialect(dialectClass = InformixDialect.class)
@Disabled
public class GoodBadUglyTest {

@BeforeEach
Expand Down

0 comments on commit e5a3870

Please sign in to comment.