Support for timezones
- add TimestampWithTimeZoneDescriptor and use it in OffsetDateTimeJD and ZonedDateTimeJD - add ZoneOffsetJavaDescriptor for ZoneOffset attributes - clean up string rendering for temporal types using ISO formats; note that they do not need to implement objectToSQLString() since they cannot be discriminators Note that at this time very few databases have meaningful support for the ANSI-standard TIMESTAMP WITH TIME ZONE type. This limits the usefulness of TimestampWithTimeZoneDescriptor for now. Also add in some missing but needed type mappings for temporal types
This commit is contained in:
parent
5a3838dfa6
commit
95930820af
|
@ -61,18 +61,6 @@ public class TimestampEpochType
|
|||
return getJavaTypeDescriptor().getComparator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String objectToSQLString(
|
||||
Date value,
|
||||
Dialect dialect) throws Exception {
|
||||
final Timestamp ts = Timestamp.class.isInstance( value )
|
||||
? ( Timestamp ) value
|
||||
: new Timestamp( value.getTime() );
|
||||
return StringType.INSTANCE.objectToSQLString(
|
||||
ts.toString(), dialect
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date fromStringValue(
|
||||
String xml) throws HibernateException {
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
package org.hibernate.type;
|
||||
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
|
||||
/**
|
||||
* Additional contract for a {@link Type} may be used for a discriminator.
|
||||
*
|
||||
|
@ -14,4 +16,15 @@ package org.hibernate.type;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface DiscriminatorType<T> extends IdentifierType<T>, LiteralType<T> {
|
||||
/**
|
||||
* Render the given discriminator value to a literal format
|
||||
* for embedding in the generated SQL.
|
||||
*
|
||||
* @param value The value to convert
|
||||
* @param dialect The SQL dialect
|
||||
*
|
||||
* @return The value's SQL literal representation
|
||||
*/
|
||||
@Override
|
||||
String objectToSQLString(T value, Dialect dialect) throws Exception;
|
||||
}
|
||||
|
|
|
@ -27,11 +27,6 @@ public class DurationType
|
|||
super( BigIntTypeDescriptor.INSTANCE, DurationJavaDescriptor.INSTANCE );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String objectToSQLString(Duration value, Dialect dialect) throws Exception {
|
||||
return String.valueOf( value.toNanos() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return Duration.class.getSimpleName();
|
||||
|
|
|
@ -43,11 +43,6 @@ public class InstantType
|
|||
super( TimestampTypeDescriptor.INSTANCE, InstantJavaDescriptor.INSTANCE );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String objectToSQLString(Instant value, Dialect dialect) throws Exception {
|
||||
return "{ts '" + FORMATTER.format( ZonedDateTime.ofInstant( value, ZoneId.of( "UTC" ) ) ) + "'}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant seed(SharedSessionContractImplementor session) {
|
||||
return Instant.now();
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.type;
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
|
||||
/**
|
||||
|
@ -29,6 +30,8 @@ public interface LiteralType<T> {
|
|||
*
|
||||
* @throws Exception Indicates an issue converting the value to literal string.
|
||||
*/
|
||||
public String objectToSQLString(T value, Dialect dialect) throws Exception;
|
||||
default String objectToSQLString(T value, Dialect dialect) throws Exception {
|
||||
throw new AssertionFailure("not a discriminator type");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ package org.hibernate.type;
|
|||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Comparator;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
|
@ -35,8 +34,6 @@ public class LocalDateTimeType
|
|||
*/
|
||||
public static final LocalDateTimeType INSTANCE = new LocalDateTimeType();
|
||||
|
||||
public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss.S", Locale.ENGLISH );
|
||||
|
||||
public LocalDateTimeType() {
|
||||
super( TimestampTypeDescriptor.INSTANCE, LocalDateTimeJavaDescriptor.INSTANCE );
|
||||
}
|
||||
|
@ -51,11 +48,6 @@ public class LocalDateTimeType
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String objectToSQLString(LocalDateTime value, Dialect dialect) throws Exception {
|
||||
return "{ts '" + FORMATTER.format( value ) + "'}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime seed(SharedSessionContractImplementor session) {
|
||||
return LocalDateTime.now();
|
||||
|
|
|
@ -8,7 +8,6 @@ package org.hibernate.type;
|
|||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Locale;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.hibernate.QueryException;
|
||||
|
@ -30,8 +29,6 @@ public class LocalDateType
|
|||
*/
|
||||
public static final LocalDateType INSTANCE = new LocalDateType();
|
||||
|
||||
public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern( "yyyy-MM-dd", Locale.ENGLISH );
|
||||
|
||||
public LocalDateType() {
|
||||
super( DateTypeDescriptor.INSTANCE, LocalDateJavaDescriptor.INSTANCE );
|
||||
}
|
||||
|
@ -46,11 +43,6 @@ public class LocalDateType
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String objectToSQLString(LocalDate value, Dialect dialect) throws Exception {
|
||||
return "{d '" + FORMATTER.format( value ) + "'}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public AllowableTemporalParameterType resolveTemporalPrecision(
|
||||
TemporalType temporalPrecision,
|
||||
|
|
|
@ -8,7 +8,6 @@ package org.hibernate.type;
|
|||
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
|
@ -31,8 +30,6 @@ public class LocalTimeType
|
|||
*/
|
||||
public static final LocalTimeType INSTANCE = new LocalTimeType();
|
||||
|
||||
public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern( "HH:mm:ss", Locale.ENGLISH );
|
||||
|
||||
public LocalTimeType() {
|
||||
super( TimeTypeDescriptor.INSTANCE, LocalTimeJavaDescriptor.INSTANCE );
|
||||
}
|
||||
|
@ -47,11 +44,6 @@ public class LocalTimeType
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String objectToSQLString(LocalTime value, Dialect dialect) throws Exception {
|
||||
return "{t '" + FORMATTER.format( value ) + "'}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public AllowableTemporalParameterType resolveTemporalPrecision(
|
||||
TemporalType temporalPrecision,
|
||||
|
|
|
@ -7,18 +7,15 @@
|
|||
package org.hibernate.type;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Comparator;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.hibernate.QueryException;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.metamodel.model.domain.AllowableTemporalParameterType;
|
||||
import org.hibernate.type.descriptor.java.OffsetDateTimeJavaDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.TimestampTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.TimestampWithTimeZoneDescriptor;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
|
@ -33,15 +30,8 @@ public class OffsetDateTimeType
|
|||
*/
|
||||
public static final OffsetDateTimeType INSTANCE = new OffsetDateTimeType();
|
||||
|
||||
public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss.S xxxxx", Locale.ENGLISH );
|
||||
|
||||
public OffsetDateTimeType() {
|
||||
super( TimestampTypeDescriptor.INSTANCE, OffsetDateTimeJavaDescriptor.INSTANCE );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String objectToSQLString(OffsetDateTime value, Dialect dialect) throws Exception {
|
||||
return "{ts '" + FORMATTER.format( value ) + "'}";
|
||||
super( TimestampWithTimeZoneDescriptor.INSTANCE, OffsetDateTimeJavaDescriptor.INSTANCE );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -8,7 +8,6 @@ package org.hibernate.type;
|
|||
|
||||
import java.time.OffsetTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
|
@ -31,17 +30,10 @@ public class OffsetTimeType
|
|||
*/
|
||||
public static final OffsetTimeType INSTANCE = new OffsetTimeType();
|
||||
|
||||
public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern( "HH:mm:ss.S xxxxx", Locale.ENGLISH );
|
||||
|
||||
public OffsetTimeType() {
|
||||
super( TimeTypeDescriptor.INSTANCE, OffsetTimeJavaDescriptor.INSTANCE );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String objectToSQLString(OffsetTime value, Dialect dialect) throws Exception {
|
||||
return "{t '" + FORMATTER.format( value ) + "'}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return OffsetTime.class.getSimpleName();
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.time.LocalDateTime;
|
|||
import java.time.LocalTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.OffsetTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Currency;
|
||||
|
@ -463,6 +464,13 @@ public final class StandardBasicTypes {
|
|||
*/
|
||||
public static final CurrencyType CURRENCY = CurrencyType.INSTANCE;
|
||||
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link java.time.ZoneOffset} to JDBC {@link java.sql.Types#VARCHAR VARCHAR}.
|
||||
*
|
||||
* @see ZoneOffsetType
|
||||
*/
|
||||
public static final ZoneOffsetType ZONE_OFFSET = ZoneOffsetType.INSTANCE;
|
||||
|
||||
/**
|
||||
* The standard Hibernate type for mapping {@link java.util.TimeZone} to JDBC {@link java.sql.Types#VARCHAR VARCHAR}.
|
||||
*
|
||||
|
@ -927,6 +935,13 @@ public final class StandardBasicTypes {
|
|||
"timezone", TimeZone.class.getName()
|
||||
);
|
||||
|
||||
handle(
|
||||
ZONE_OFFSET,
|
||||
"org.hibernate.type.ZoneOffsetType",
|
||||
basicTypeRegistry,
|
||||
ZoneOffset.class.getSimpleName(), ZoneOffset.class.getName()
|
||||
);
|
||||
|
||||
handle(
|
||||
URL,
|
||||
"org.hibernate.type.UrlType",
|
||||
|
|
|
@ -50,14 +50,6 @@ public class TimeType
|
|||
// return true;
|
||||
// }
|
||||
|
||||
public String objectToSQLString(Date value, Dialect dialect) throws Exception {
|
||||
Time jdbcTime = Time.class.isInstance( value )
|
||||
? ( Time ) value
|
||||
: new Time( value.getTime() );
|
||||
// TODO : use JDBC time literal escape syntax? -> {t 'time-string'} in hh:mm:ss format
|
||||
return StringType.INSTANCE.objectToSQLString( jdbcTime.toString(), dialect );
|
||||
}
|
||||
|
||||
@Override
|
||||
public AllowableTemporalParameterType resolveTemporalPrecision(
|
||||
TemporalType temporalPrecision,
|
||||
|
|
|
@ -62,15 +62,6 @@ public class TimestampType
|
|||
return getJavaTypeDescriptor().getComparator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String objectToSQLString(Date value, Dialect dialect) throws Exception {
|
||||
final Timestamp ts = Timestamp.class.isInstance( value )
|
||||
? ( Timestamp ) value
|
||||
: new Timestamp( value.getTime() );
|
||||
// TODO : use JDBC date literal escape syntax? -> {d 'date-string'} in yyyy-mm-dd hh:mm:ss[.f...] format
|
||||
return StringType.INSTANCE.objectToSQLString( ts.toString(), dialect );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date fromStringValue(String xml) throws HibernateException {
|
||||
return fromString( xml );
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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>.
|
||||
*/
|
||||
package org.hibernate.type;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.type.descriptor.java.ZoneOffsetJavaDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor;
|
||||
|
||||
import java.time.ZoneOffset;
|
||||
|
||||
/**
|
||||
* A type mapping {@link java.sql.Types#VARCHAR VARCHAR} and {@link ZoneOffset}
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ZoneOffsetType
|
||||
extends AbstractSingleColumnStandardBasicType<ZoneOffset>
|
||||
implements LiteralType<ZoneOffset> {
|
||||
|
||||
public static final ZoneOffsetType INSTANCE = new ZoneOffsetType();
|
||||
|
||||
public ZoneOffsetType() {
|
||||
super( VarcharTypeDescriptor.INSTANCE, ZoneOffsetJavaDescriptor.INSTANCE );
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return ZoneOffset.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean registerUnderJavaType() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String objectToSQLString(ZoneOffset value, Dialect dialect) throws Exception {
|
||||
return StringType.INSTANCE.objectToSQLString( value.getId(), dialect );
|
||||
}
|
||||
|
||||
}
|
|
@ -20,6 +20,7 @@ import org.hibernate.internal.util.ZonedDateTimeComparator;
|
|||
import org.hibernate.metamodel.model.domain.AllowableTemporalParameterType;
|
||||
import org.hibernate.type.descriptor.java.ZonedDateTimeJavaDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.TimestampTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.TimestampWithTimeZoneDescriptor;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
|
@ -34,15 +35,8 @@ public class ZonedDateTimeType
|
|||
*/
|
||||
public static final ZonedDateTimeType INSTANCE = new ZonedDateTimeType();
|
||||
|
||||
public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss.S VV", Locale.ENGLISH );
|
||||
|
||||
public ZonedDateTimeType() {
|
||||
super( TimestampTypeDescriptor.INSTANCE, ZonedDateTimeJavaDescriptor.INSTANCE );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String objectToSQLString(ZonedDateTime value, Dialect dialect) throws Exception {
|
||||
return "{ts '" + FORMATTER.format( value ) + "'}";
|
||||
super( TimestampWithTimeZoneDescriptor.INSTANCE, ZonedDateTimeJavaDescriptor.INSTANCE );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,11 +12,11 @@ import java.time.LocalDate;
|
|||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.hibernate.type.LocalDateType;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
|
||||
/**
|
||||
|
@ -37,12 +37,12 @@ public class LocalDateJavaDescriptor extends AbstractTypeDescriptor<LocalDate> {
|
|||
|
||||
@Override
|
||||
public String toString(LocalDate value) {
|
||||
return LocalDateType.FORMATTER.format( value );
|
||||
return DateTimeFormatter.ISO_LOCAL_DATE.format( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDate fromString(String string) {
|
||||
return LocalDate.from( LocalDateType.FORMATTER.parse( string ) );
|
||||
return LocalDate.from( DateTimeFormatter.ISO_LOCAL_DATE.parse( string ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -10,12 +10,12 @@ import java.sql.Timestamp;
|
|||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.type.LocalDateTimeType;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
|
||||
/**
|
||||
|
@ -36,12 +36,12 @@ public class LocalDateTimeJavaDescriptor extends AbstractTypeDescriptor<LocalDat
|
|||
|
||||
@Override
|
||||
public String toString(LocalDateTime value) {
|
||||
return LocalDateTimeType.FORMATTER.format( value );
|
||||
return DateTimeFormatter.ISO_DATE_TIME.format( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime fromString(String string) {
|
||||
return LocalDateTime.from( LocalDateTimeType.FORMATTER.parse( string ) );
|
||||
return LocalDateTime.from( DateTimeFormatter.ISO_DATE_TIME.parse( string ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -14,12 +14,12 @@ import java.time.LocalDateTime;
|
|||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.type.LocalTimeType;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
|
||||
/**
|
||||
|
@ -40,12 +40,12 @@ public class LocalTimeJavaDescriptor extends AbstractTypeDescriptor<LocalTime> {
|
|||
|
||||
@Override
|
||||
public String toString(LocalTime value) {
|
||||
return LocalTimeType.FORMATTER.format( value );
|
||||
return DateTimeFormatter.ISO_LOCAL_TIME.format( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalTime fromString(String string) {
|
||||
return LocalTime.from( LocalTimeType.FORMATTER.parse( string ) );
|
||||
return LocalTime.from( DateTimeFormatter.ISO_LOCAL_TIME.parse( string ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -10,16 +10,17 @@ import java.sql.Timestamp;
|
|||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.type.OffsetDateTimeType;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
|
||||
/**
|
||||
* Java type descriptor for the LocalDateTime type.
|
||||
* Java type descriptor for the {@link OffsetDateTime} type.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
@ -36,12 +37,12 @@ public class OffsetDateTimeJavaDescriptor extends AbstractTypeDescriptor<OffsetD
|
|||
|
||||
@Override
|
||||
public String toString(OffsetDateTime value) {
|
||||
return OffsetDateTimeType.FORMATTER.format( value );
|
||||
return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public OffsetDateTime fromString(String string) {
|
||||
return OffsetDateTime.from( OffsetDateTimeType.FORMATTER.parse( string ) );
|
||||
return OffsetDateTime.from( DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse( string ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -55,6 +56,10 @@ public class OffsetDateTimeJavaDescriptor extends AbstractTypeDescriptor<OffsetD
|
|||
return (X) offsetDateTime;
|
||||
}
|
||||
|
||||
if ( ZonedDateTime.class.isAssignableFrom( type ) ) {
|
||||
return (X) offsetDateTime.toZonedDateTime();
|
||||
}
|
||||
|
||||
if ( Calendar.class.isAssignableFrom( type ) ) {
|
||||
return (X) GregorianCalendar.from( offsetDateTime.toZonedDateTime() );
|
||||
}
|
||||
|
@ -109,6 +114,11 @@ public class OffsetDateTimeJavaDescriptor extends AbstractTypeDescriptor<OffsetD
|
|||
return (OffsetDateTime) value;
|
||||
}
|
||||
|
||||
if ( ZonedDateTime.class.isInstance( value ) ) {
|
||||
ZonedDateTime zonedDateTime = (ZonedDateTime) value;
|
||||
return OffsetDateTime.of( zonedDateTime.toLocalDateTime(), zonedDateTime.getOffset() );
|
||||
}
|
||||
|
||||
if ( Timestamp.class.isInstance( value ) ) {
|
||||
final Timestamp ts = (Timestamp) value;
|
||||
/*
|
||||
|
|
|
@ -14,12 +14,12 @@ import java.time.OffsetDateTime;
|
|||
import java.time.OffsetTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.type.OffsetTimeType;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
|
||||
/**
|
||||
|
@ -40,12 +40,12 @@ public class OffsetTimeJavaDescriptor extends AbstractTypeDescriptor<OffsetTime>
|
|||
|
||||
@Override
|
||||
public String toString(OffsetTime value) {
|
||||
return OffsetTimeType.FORMATTER.format( value );
|
||||
return DateTimeFormatter.ISO_OFFSET_TIME.format( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public OffsetTime fromString(String string) {
|
||||
return OffsetTime.from( OffsetTimeType.FORMATTER.parse( string ) );
|
||||
return OffsetTime.from( DateTimeFormatter.ISO_OFFSET_TIME.parse( string ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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>.
|
||||
*/
|
||||
package org.hibernate.type.descriptor.java;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators;
|
||||
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Descriptor for {@link ZoneOffset} handling.
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class ZoneOffsetJavaDescriptor extends AbstractTypeDescriptor<ZoneOffset> {
|
||||
public static final ZoneOffsetJavaDescriptor INSTANCE = new ZoneOffsetJavaDescriptor();
|
||||
|
||||
public static class ZoneOffsetComparator implements Comparator<ZoneOffset> {
|
||||
public static final ZoneOffsetComparator INSTANCE = new ZoneOffsetComparator();
|
||||
|
||||
public int compare(ZoneOffset o1, ZoneOffset o2) {
|
||||
return o1.getId().compareTo( o2.getId() );
|
||||
}
|
||||
}
|
||||
|
||||
public ZoneOffsetJavaDescriptor() {
|
||||
super( ZoneOffset.class );
|
||||
}
|
||||
|
||||
public String toString(ZoneOffset value) {
|
||||
return value.getId();
|
||||
}
|
||||
|
||||
public ZoneOffset fromString(String string) {
|
||||
return ZoneOffset.of( string );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlTypeDescriptor getJdbcRecommendedSqlType(SqlTypeDescriptorIndicators context) {
|
||||
return StringTypeDescriptor.INSTANCE.getJdbcRecommendedSqlType( context );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparator<ZoneOffset> getComparator() {
|
||||
return ZoneOffsetComparator.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public <X> X unwrap(ZoneOffset value, Class<X> type, WrapperOptions wrapperOptions) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
if ( String.class.isAssignableFrom( type ) ) {
|
||||
return (X) toString( value );
|
||||
}
|
||||
throw unknownUnwrap( type );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> ZoneOffset wrap(X value, WrapperOptions wrapperOptions) {
|
||||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
if ( String.class.isInstance( value ) ) {
|
||||
return fromString( (String) value );
|
||||
}
|
||||
throw unknownWrap( value.getClass() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDefaultSqlLength(Dialect dialect) {
|
||||
return 6;
|
||||
}
|
||||
}
|
|
@ -8,18 +8,19 @@ package org.hibernate.type.descriptor.java;
|
|||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.type.ZonedDateTimeType;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
|
||||
/**
|
||||
* Java type descriptor for the LocalDateTime type.
|
||||
* Java type descriptor for the {@link ZonedDateTime} type.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
@ -36,12 +37,12 @@ public class ZonedDateTimeJavaDescriptor extends AbstractTypeDescriptor<ZonedDat
|
|||
|
||||
@Override
|
||||
public String toString(ZonedDateTime value) {
|
||||
return ZonedDateTimeType.FORMATTER.format( value );
|
||||
return DateTimeFormatter.ISO_ZONED_DATE_TIME.format( value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZonedDateTime fromString(String string) {
|
||||
return ZonedDateTime.from( ZonedDateTimeType.FORMATTER.parse( string ) );
|
||||
return ZonedDateTime.from( DateTimeFormatter.ISO_ZONED_DATE_TIME.parse( string ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -55,6 +56,10 @@ public class ZonedDateTimeJavaDescriptor extends AbstractTypeDescriptor<ZonedDat
|
|||
return (X) zonedDateTime;
|
||||
}
|
||||
|
||||
if ( OffsetDateTime.class.isAssignableFrom( type ) ) {
|
||||
return (X) OffsetDateTime.of( zonedDateTime.toLocalDateTime(), zonedDateTime.getOffset() );
|
||||
}
|
||||
|
||||
if ( Calendar.class.isAssignableFrom( type ) ) {
|
||||
return (X) GregorianCalendar.from( zonedDateTime );
|
||||
}
|
||||
|
@ -109,6 +114,11 @@ public class ZonedDateTimeJavaDescriptor extends AbstractTypeDescriptor<ZonedDat
|
|||
return (ZonedDateTime) value;
|
||||
}
|
||||
|
||||
if ( OffsetDateTime.class.isInstance( value ) ) {
|
||||
OffsetDateTime offsetDateTime = (OffsetDateTime) value;
|
||||
return offsetDateTime.toZonedDateTime();
|
||||
}
|
||||
|
||||
if ( java.sql.Timestamp.class.isInstance( value ) ) {
|
||||
final Timestamp ts = (Timestamp) value;
|
||||
/*
|
||||
|
|
|
@ -18,6 +18,11 @@ import java.sql.Struct;
|
|||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
@ -112,6 +117,11 @@ public class JdbcTypeJavaClassMappings {
|
|||
workMap.put( java.sql.Date.class, Types.DATE );
|
||||
workMap.put( Time.class, Types.TIME );
|
||||
workMap.put( Timestamp.class, Types.TIMESTAMP );
|
||||
workMap.put( LocalTime.class, Types.TIME );
|
||||
workMap.put( LocalDate.class, Types.DATE );
|
||||
workMap.put( LocalDateTime.class, Types.TIMESTAMP );
|
||||
workMap.put( OffsetDateTime.class, Types.TIMESTAMP_WITH_TIMEZONE );
|
||||
workMap.put( ZonedDateTime.class, Types.TIMESTAMP_WITH_TIMEZONE );
|
||||
workMap.put( Blob.class, Types.BLOB );
|
||||
workMap.put( Clob.class, Types.CLOB );
|
||||
workMap.put( Array.class, Types.ARRAY );
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* 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>.
|
||||
*/
|
||||
package org.hibernate.type.descriptor.sql;
|
||||
|
||||
import org.hibernate.type.descriptor.ValueBinder;
|
||||
import org.hibernate.type.descriptor.ValueExtractor;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.internal.JdbcLiteralFormatterTemporal;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import javax.persistence.TemporalType;
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
/**
|
||||
* Descriptor for {@link Types#TIMESTAMP_WITH_TIMEZONE TIMESTAMP_WITH_TIMEZONE} handling.
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class TimestampWithTimeZoneDescriptor implements SqlTypeDescriptor {
|
||||
public static final TimestampWithTimeZoneDescriptor INSTANCE = new TimestampWithTimeZoneDescriptor();
|
||||
|
||||
public TimestampWithTimeZoneDescriptor() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSqlType() {
|
||||
return Types.TIMESTAMP_WITH_TIMEZONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeRemapped() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> BasicJavaDescriptor<T> getJdbcRecommendedJavaTypeMapping(TypeConfiguration typeConfiguration) {
|
||||
return (BasicJavaDescriptor<T>) typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( OffsetDateTime.class );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaTypeDescriptor<T> javaTypeDescriptor) {
|
||||
return new JdbcLiteralFormatterTemporal( javaTypeDescriptor, TemporalType.TIMESTAMP );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {
|
||||
return new BasicBinder<X>( javaTypeDescriptor, this ) {
|
||||
@Override
|
||||
protected void doBind(
|
||||
PreparedStatement st,
|
||||
X value,
|
||||
int index,
|
||||
WrapperOptions wrapperOptions) throws SQLException {
|
||||
try {
|
||||
final OffsetDateTime dateTime = javaTypeDescriptor.unwrap( value, OffsetDateTime.class, wrapperOptions.getSession() );
|
||||
// supposed to be supported in JDBC 4.2
|
||||
st.setObject( index, dateTime, Types.TIMESTAMP_WITH_TIMEZONE );
|
||||
}
|
||||
catch (SQLException|AbstractMethodError e) {
|
||||
// fall back to treating it as a JDBC Timestamp
|
||||
final Timestamp timestamp = javaTypeDescriptor.unwrap( value, Timestamp.class, wrapperOptions.getSession() );
|
||||
st.setTimestamp( index, timestamp );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBind(
|
||||
CallableStatement st,
|
||||
X value,
|
||||
String name,
|
||||
WrapperOptions wrapperOptions)
|
||||
throws SQLException {
|
||||
try {
|
||||
final OffsetDateTime dateTime = javaTypeDescriptor.unwrap( value, OffsetDateTime.class, wrapperOptions.getSession() );
|
||||
// supposed to be supported in JDBC 4.2
|
||||
st.setObject( name, dateTime, Types.TIMESTAMP_WITH_TIMEZONE );
|
||||
}
|
||||
catch (SQLException|AbstractMethodError e) {
|
||||
// fall back to treating it as a JDBC Timestamp
|
||||
final Timestamp timestamp = javaTypeDescriptor.unwrap( value, Timestamp.class, wrapperOptions.getSession() );
|
||||
st.setTimestamp( name, timestamp );
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> ValueExtractor<X> getExtractor(final JavaTypeDescriptor<X> javaTypeDescriptor) {
|
||||
return new BasicExtractor<X>( javaTypeDescriptor, this ) {
|
||||
@Override
|
||||
protected X doExtract(ResultSet rs, int position, WrapperOptions wrapperOptions) throws SQLException {
|
||||
try {
|
||||
// supposed to be supported in JDBC 4.2
|
||||
return javaTypeDescriptor.wrap( rs.getObject( position, OffsetDateTime.class ), wrapperOptions.getSession() );
|
||||
}
|
||||
catch (SQLException|AbstractMethodError e) {
|
||||
// fall back to treating it as a JDBC Timestamp
|
||||
return javaTypeDescriptor.wrap( rs.getTimestamp( position ), wrapperOptions.getSession() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected X doExtract(CallableStatement statement, int position, WrapperOptions wrapperOptions) throws SQLException {
|
||||
try {
|
||||
// supposed to be supported in JDBC 4.2
|
||||
return javaTypeDescriptor.wrap( statement.getObject( position, OffsetDateTime.class ), wrapperOptions.getSession() );
|
||||
}
|
||||
catch (SQLException|AbstractMethodError e) {
|
||||
// fall back to treating it as a JDBC Timestamp
|
||||
return javaTypeDescriptor.wrap( statement.getTimestamp( position ), wrapperOptions.getSession() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected X doExtract(CallableStatement statement, String name, WrapperOptions wrapperOptions) throws SQLException {
|
||||
try {
|
||||
// supposed to be supported in JDBC 4.2
|
||||
return javaTypeDescriptor.wrap( statement.getObject( name, OffsetDateTime.class ), wrapperOptions.getSession() );
|
||||
}
|
||||
catch (SQLException|AbstractMethodError e) {
|
||||
// fall back to treating it as a JDBC Timestamp
|
||||
return javaTypeDescriptor.wrap( statement.getTimestamp( name ), wrapperOptions.getSession() );
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue