Skip to content
Merged
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 @@ -6,11 +6,11 @@

import java.sql.Types;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
Expand Down Expand Up @@ -114,7 +114,7 @@ public Date coerce(Object value, CoercionContext coercionContext) {
return wrap( value, null );
}

@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public Object unwrap(Date value, Class type, WrapperOptions options) {
if ( value == null ) {
Expand Down Expand Up @@ -169,16 +169,17 @@ private java.sql.Date unwrapSqlDate(Date value) {
final long dateEpoch = toDateEpoch( date.getTime() );
return dateEpoch == date.getTime() ? date : new java.sql.Date( dateEpoch );
}
return new java.sql.Date( unwrapDateEpoch( value ) );

else {
return new java.sql.Date( unwrapDateEpoch( value ) );
}
}

private static long unwrapDateEpoch(Date value) {
return toDateEpoch( value.getTime() );
}

private static long toDateEpoch(long value) {
Calendar calendar = Calendar.getInstance();
final var calendar = Calendar.getInstance();
calendar.setTimeInMillis( value );
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.clear(Calendar.MINUTE);
Expand Down Expand Up @@ -216,14 +217,15 @@ public Date wrap(Object value, WrapperOptions options) {
throw unknownWrap( value.getClass() );
}

private static TemporalAccessor fromDate(Date value) {
return value instanceof java.sql.Date date
? date.toLocalDate()
: LocalDate.ofInstant( value.toInstant(), ZoneOffset.systemDefault() );
}

@Override
public String toString(Date value) {
if ( value instanceof java.sql.Date ) {
return LITERAL_FORMATTER.format( ( (java.sql.Date) value ).toLocalDate() );
}
else {
return LITERAL_FORMATTER.format( LocalDate.ofInstant( value.toInstant(), ZoneOffset.systemDefault() ) );
}
return LITERAL_FORMATTER.format( fromDate( value ) );
}

@Override
Expand All @@ -250,12 +252,7 @@ public Date fromEncodedString(CharSequence charSequence, int start, int end) {

@Override
public void appendEncodedString(SqlAppender sb, Date value) {
if ( value instanceof java.sql.Date ) {
LITERAL_FORMATTER.formatTo( ( (java.sql.Date) value ).toLocalDate(), sb );
}
else {
LITERAL_FORMATTER.formatTo( LocalTime.ofInstant( value.toInstant(), ZoneOffset.systemDefault() ), sb );
}
LITERAL_FORMATTER.formatTo( fromDate( value ), sb );
}

@Override
Expand All @@ -274,12 +271,9 @@ public static class DateMutabilityPlan extends MutableMutabilityPlan<Date> {

@Override
public Date deepCopyNotNull(Date value) {
if ( value instanceof java.sql.Date ) {
return value;
}
else {
return new java.sql.Date( value.getTime() );
}
return value instanceof java.sql.Date
? value
: new java.sql.Date( value.getTime() );
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,18 @@ public Date coerce(Object value, CoercionContext coercionContext) {
return wrap( value, null );
}

@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public Object unwrap(Date value, Class type, WrapperOptions options) {
if ( value == null ) {
return null;
}

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 );
final var time =
value instanceof java.sql.Time
? (java.sql.Time) value
: new java.sql.Time( value.getTime() % 86_400_000 );
final var localTime = time.toLocalTime();
long millis = time.getTime() % 1000;
if ( millis == 0 ) {
Expand Down Expand Up @@ -209,14 +210,15 @@ public Date wrap(Object value, WrapperOptions options) {
throw unknownWrap( value.getClass() );
}

private static LocalTime fromDate(Date value) {
return value instanceof Time time
? time.toLocalTime()
: LocalTime.ofInstant( value.toInstant(), ZoneOffset.systemDefault() );
}

@Override
public String toString(Date value) {
if ( value instanceof java.sql.Time time ) {
return LITERAL_FORMATTER.format( time.toLocalTime() );
}
else {
return LITERAL_FORMATTER.format( LocalTime.ofInstant( value.toInstant(), ZoneOffset.systemDefault() ) );
}
return LITERAL_FORMATTER.format( fromDate( value ) );
}

@Override
Expand Down Expand Up @@ -246,12 +248,7 @@ public Date fromEncodedString(CharSequence charSequence, int start, int end) {

@Override
public void appendEncodedString(SqlAppender sb, Date value) {
if ( value instanceof java.sql.Time time ) {
LITERAL_FORMATTER.formatTo( time.toLocalTime(), sb );
}
else {
LITERAL_FORMATTER.formatTo( LocalTime.ofInstant( value.toInstant(), ZoneOffset.systemDefault() ), sb );
}
LITERAL_FORMATTER.formatTo( fromDate( value ), sb );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
Expand Down Expand Up @@ -120,7 +119,7 @@ public Date coerce(Object value, CoercionContext coercionContext) {
return wrap( value, null );
}

@SuppressWarnings({ "unchecked", "rawtypes" })
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public Object unwrap(Date value, Class type, WrapperOptions options) {
if ( value == null ) {
Expand All @@ -138,7 +137,7 @@ public Object unwrap(Date value, Class type, WrapperOptions options) {
}

if ( LocalDateTime.class.isAssignableFrom( type ) ) {
final Instant instant = value.toInstant();
final var instant = value.toInstant();
return LocalDateTime.ofInstant( instant, ZoneId.systemDefault() );
}

Expand Down Expand Up @@ -230,15 +229,14 @@ public void appendEncodedString(SqlAppender sb, Date value) {
public Date fromEncodedString(CharSequence charSequence, int start, int end) {
try {
final var temporalAccessor = ENCODED_FORMATTER.parse( subSequence( charSequence, start, end ) );
final Timestamp timestamp;
if ( temporalAccessor.isSupported( ChronoField.INSTANT_SECONDS ) ) {
timestamp = new Timestamp( temporalAccessor.getLong( ChronoField.INSTANT_SECONDS ) * 1000L );
final var timestamp = new Timestamp( temporalAccessor.getLong( ChronoField.INSTANT_SECONDS ) * 1000L );
timestamp.setNanos( temporalAccessor.get( ChronoField.NANO_OF_SECOND ) );
return timestamp;
}
else {
timestamp = Timestamp.valueOf( LocalDateTime.from( temporalAccessor ) );
return Timestamp.valueOf( LocalDateTime.from( temporalAccessor ) );
}
return timestamp;
}
catch ( DateTimeParseException pe) {
throw new HibernateException( "could not parse timestamp string " + subSequence( charSequence, start, end ), pe );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,11 @@ public <X> X unwrap(LocalDate value, Class<X> type, WrapperOptions options) {
final LocalDateTime localDateTime = value.atStartOfDay();

if ( Timestamp.class.isAssignableFrom( type ) ) {
/*
* Workaround for HHH-13266 (JDK-8061577).
* We could have done Timestamp.from( localDateTime.atZone( ZoneId.systemDefault() ).toInstant() ),
* but on top of being more complex than the line below, it won't always work.
* Timestamp.from() assumes the number of milliseconds since the epoch
* means the same thing in Timestamp and Instant, but it doesn't, in particular before 1900.
*/
// Workaround for HHH-13266 (JDK-8061577).
// We could have done Timestamp.from( localDateTime.atZone( ZoneId.systemDefault() ).toInstant() ),
// but on top of being more complex than the line below, it won't always work.
// Timestamp.from() assumes the number of milliseconds since the epoch means the
// same thing in Timestamp and Instant, but it doesn't, in particular before 1900.
return (X) Timestamp.valueOf( localDateTime );
}

Expand Down Expand Up @@ -134,13 +132,11 @@ public <X> LocalDate wrap(X value, WrapperOptions options) {
}

if (value instanceof Timestamp timestamp) {
/*
* Workaround for HHH-13266 (JDK-8061577).
* We used to do LocalDateTime.ofInstant( ts.toInstant(), ZoneId.systemDefault() ).toLocalDate(),
* but on top of being more complex than the line below, it won't always work.
* ts.toInstant() assumes the number of milliseconds since the epoch
* means the same thing in Timestamp and Instant, but it doesn't, in particular before 1900.
*/
// Workaround for HHH-13266 (JDK-8061577).
// We used to do LocalDateTime.ofInstant( ts.toInstant(), ZoneId.systemDefault() ).toLocalDate(),
// but on top of being more complex than the line below, it won't always work.
// ts.toInstant() assumes the number of milliseconds since the epoch means the
// same thing in Timestamp and Instant, but it doesn't, in particular before 1900.
return timestamp.toLocalDateTime().toLocalDate();
}

Expand All @@ -154,12 +150,9 @@ public <X> LocalDate wrap(X value, WrapperOptions options) {
}

if (value instanceof Date date) {
if (value instanceof java.sql.Date sqlDate) {
return sqlDate.toLocalDate();
}
else {
return Instant.ofEpochMilli( date.getTime() ).atZone( ZoneId.systemDefault() ).toLocalDate();
}
return value instanceof java.sql.Date sqlDate
? sqlDate.toLocalDate()
: Instant.ofEpochMilli( date.getTime() ).atZone( ZoneId.systemDefault() ).toLocalDate();
}

throw unknownWrap( value.getClass() );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,11 @@ public <X> X unwrap(LocalDateTime value, Class<X> type, WrapperOptions options)
}

if ( Timestamp.class.isAssignableFrom( type ) ) {
/*
* Workaround for HHH-13266 (JDK-8061577).
* We used to do Timestamp.from( value.atZone( ZoneId.systemDefault() ).toInstant() ),
* but on top of being more complex than the line below, it won't always work.
* Timestamp.from() assumes the number of milliseconds since the epoch
* means the same thing in Timestamp and Instant, but it doesn't, in particular before 1900.
*/
// Workaround for HHH-13266 (JDK-8061577).
// We used to do Timestamp.from( value.atZone( ZoneId.systemDefault() ).toInstant() ),
// but on top of being more complex than the line below, it won't always work.
// Timestamp.from() assumes the number of milliseconds since the epoch means the
// same thing in Timestamp and Instant, but it doesn't, in particular before 1900.
return (X) Timestamp.valueOf( value );
}

Expand Down Expand Up @@ -137,13 +135,11 @@ public <X> LocalDateTime wrap(X value, WrapperOptions options) {
}

if (value instanceof Timestamp timestamp) {
/*
* Workaround for HHH-13266 (JDK-8061577).
* We used to do LocalDateTime.ofInstant( ts.toInstant(), ZoneId.systemDefault() ),
* but on top of being more complex than the line below, it won't always work.
* ts.toInstant() assumes the number of milliseconds since the epoch
* means the same thing in Timestamp and Instant, but it doesn't, in particular before 1900.
*/
// Workaround for HHH-13266 (JDK-8061577).
// We used to do LocalDateTime.ofInstant( ts.toInstant(), ZoneId.systemDefault() ),
// but on top of being more complex than the line below, it won't always work.
// ts.toInstant() assumes the number of milliseconds since the epoch means the
// same thing in Timestamp and Instant, but it doesn't, in particular before 1900.
return timestamp.toLocalDateTime();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@

import org.hibernate.dialect.Dialect;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.DateTimeUtils;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.spi.TypeConfiguration;

import static org.hibernate.type.descriptor.DateTimeUtils.roundToPrecision;

/**
* Java type descriptor for the {@link LocalTime} type.
*
Expand Down Expand Up @@ -94,19 +95,20 @@ public <X> X unwrap(LocalTime value, Class<X> type, WrapperOptions options) {

if ( Time.class.isAssignableFrom( type ) ) {
final var time = Time.valueOf( value );
if ( value.getNano() == 0 ) {
return (X) time;
}
// Preserve milliseconds, which java.sql.Time supports
return (X) new Time( time.getTime() + DateTimeUtils.roundToPrecision( value.getNano(), 3 ) / 1000000 );
final int nanos = value.getNano();
return nanos == 0
? (X) time
// Preserve milliseconds, which java.sql.Time supports
: (X) new Time( time.getTime() + roundToPrecision( nanos, 3 ) / 1000000 );
}

// Oracle documentation says to set the Date to January 1, 1970 when convert from
// a LocalTime to a Calendar. IMO the same should hold true for converting to all
// the legacy Date/Time types...

// a LocalTime to a Calendar. IMO the same should hold true for converting to all
// the legacy Date/Time types.

final var zonedDateTime = value.atDate( LocalDate.of( 1970, 1, 1 ) ).atZone( ZoneId.systemDefault() );
final var zonedDateTime =
value.atDate( LocalDate.of( 1970, 1, 1 ) )
.atZone( ZoneId.systemDefault() );

if ( Calendar.class.isAssignableFrom( type ) ) {
return (X) GregorianCalendar.from( zonedDateTime );
Expand Down Expand Up @@ -140,7 +142,7 @@ public <X> LocalTime wrap(X value, WrapperOptions options) {
}

if (value instanceof Time time) {
final LocalTime localTime = time.toLocalTime();
final var localTime = time.toLocalTime();
long millis = time.getTime() % 1000;
if ( millis == 0 ) {
return localTime;
Expand Down
Loading
Loading