HHH-18532 Suggested fix to conversion of epoch time in milliseconds to java.sql.Time
This commit is contained in:
parent
871c203777
commit
7b560a8bbd
|
@ -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;
|
||||
|
@ -60,6 +64,13 @@ public abstract class AbstractTemporalJavaType<T>
|
|||
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"
|
||||
|
|
|
@ -100,7 +100,7 @@ public class CalendarDateJavaType extends AbstractTemporalJavaType<Calendar> {
|
|||
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() );
|
||||
|
|
|
@ -117,7 +117,7 @@ public class CalendarJavaType extends AbstractTemporalJavaType<Calendar> impleme
|
|||
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() );
|
||||
|
|
|
@ -102,7 +102,7 @@ public class CalendarTimeJavaType extends AbstractTemporalJavaType<Calendar> {
|
|||
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() );
|
||||
|
|
|
@ -124,7 +124,7 @@ public class DateJavaType extends AbstractTemporalJavaType<Date> implements Vers
|
|||
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 ) ) {
|
||||
|
|
|
@ -126,7 +126,7 @@ public class InstantJavaType extends AbstractTemporalJavaType<Instant>
|
|||
}
|
||||
|
||||
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 ) ) {
|
||||
|
|
|
@ -120,7 +120,7 @@ public class JdbcTimeJavaType extends AbstractTemporalJavaType<Date> {
|
|||
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 ) {
|
||||
|
@ -135,9 +135,7 @@ public class JdbcTimeJavaType extends AbstractTemporalJavaType<Date> {
|
|||
}
|
||||
|
||||
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 ) ) {
|
||||
|
@ -175,12 +173,8 @@ public class JdbcTimeJavaType extends AbstractTemporalJavaType<Date> {
|
|||
return null;
|
||||
}
|
||||
|
||||
if ( value instanceof Time ) {
|
||||
return (Date) value;
|
||||
}
|
||||
|
||||
if ( value instanceof Date ) {
|
||||
return new Time( ( (Date) value ).getTime() % 86_400_000 );
|
||||
return millisToSqlTime( ( (Date) value ).getTime() );
|
||||
}
|
||||
|
||||
if ( value instanceof LocalTime ) {
|
||||
|
@ -198,7 +192,7 @@ public class JdbcTimeJavaType extends AbstractTemporalJavaType<Date> {
|
|||
}
|
||||
|
||||
if ( value instanceof Calendar ) {
|
||||
return new Time( ( (Calendar) value ).getTimeInMillis() % 86_400_000 );
|
||||
return millisToSqlTime( ( (Calendar) value ).getTimeInMillis() );
|
||||
}
|
||||
|
||||
throw unknownWrap( value.getClass() );
|
||||
|
|
|
@ -137,7 +137,7 @@ public class JdbcTimestampJavaType extends AbstractTemporalJavaType<Date> implem
|
|||
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 ) ) {
|
||||
|
|
|
@ -102,7 +102,7 @@ public class LocalDateTimeJavaType extends AbstractTemporalJavaType<LocalDateTim
|
|||
|
||||
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 ) ) {
|
||||
|
|
|
@ -157,7 +157,7 @@ public class OffsetDateTimeJavaType extends AbstractTemporalJavaType<OffsetDateT
|
|||
}
|
||||
|
||||
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 ) ) {
|
||||
|
|
|
@ -124,7 +124,7 @@ public class ZonedDateTimeJavaType extends AbstractTemporalJavaType<ZonedDateTim
|
|||
}
|
||||
|
||||
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 ) ) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -17,15 +15,8 @@ import java.time.OffsetTime;
|
|||
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;
|
||||
|
@ -173,7 +164,7 @@ public class DateSubclassesUnwrapTest {
|
|||
|
||||
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 ) );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -43,7 +47,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
@DomainModel(annotatedClasses = GoodBadUglyTest.Times.class)
|
||||
@SessionFactory
|
||||
@SkipForDialect(dialectClass = InformixDialect.class)
|
||||
@Disabled
|
||||
public class GoodBadUglyTest {
|
||||
|
||||
@BeforeEach
|
||||
|
|
Loading…
Reference in New Issue