HHH-8844 - Add support for Java 8 date and time types (JSR-310)

This commit is contained in:
Steve Ebersole 2015-03-24 20:25:17 -05:00
parent e44b38f716
commit 30ceca18c2
5 changed files with 234 additions and 1 deletions

View File

@ -1,5 +1,4 @@
dependencies {
provided( libraries.validation )
compile project( ':hibernate-core' )
compile( libraries.c3p0 )

View File

@ -43,5 +43,6 @@ public class Java8DateTimeTypeContributor implements TypeContributor {
typeContributions.contributeType( ZonedDateTimeType.INSTANCE );
typeContributions.contributeType( OffsetDateTimeType.INSTANCE );
typeContributions.contributeType( OffsetTimeType.INSTANCE );
}
}

View File

@ -0,0 +1,85 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.type;
import java.time.OffsetTime;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.Locale;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.util.compare.ComparableComparator;
import org.hibernate.type.descriptor.java.OffsetTimeJavaDescriptor;
import org.hibernate.type.descriptor.sql.TimestampTypeDescriptor;
/**
* @author Steve Ebersole
*/
public class OffsetTimeType
extends AbstractSingleColumnStandardBasicType<OffsetTime>
implements VersionType<OffsetTime>, LiteralType<OffsetTime> {
/**
* Singleton access
*/
public static final OffsetTimeType INSTANCE = new OffsetTimeType();
public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern( "HH:mm:ss.S xxxxx", Locale.ENGLISH );
public OffsetTimeType() {
super( TimestampTypeDescriptor.INSTANCE, OffsetTimeJavaDescriptor.INSTANCE );
}
@Override
public String objectToSQLString(OffsetTime value, Dialect dialect) throws Exception {
return "{ts '" + FORMATTER.format( value ) + "'}";
}
@Override
public OffsetTime seed(SessionImplementor session) {
return OffsetTime.now();
}
@Override
public OffsetTime next(OffsetTime current, SessionImplementor session) {
return OffsetTime.now();
}
@Override
@SuppressWarnings("unchecked")
public Comparator<OffsetTime> getComparator() {
return ComparableComparator.INSTANCE;
}
@Override
public String getName() {
return OffsetTime.class.getSimpleName();
}
@Override
protected boolean registerUnderJavaType() {
return true;
}
}

View File

@ -0,0 +1,138 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2015, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.type.descriptor.java;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDate;
import java.time.OffsetTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import org.hibernate.type.OffsetTimeType;
import org.hibernate.type.descriptor.WrapperOptions;
/**
* Java type descriptor for the LocalDateTime type.
*
* @author Steve Ebersole
*/
public class OffsetTimeJavaDescriptor extends AbstractTypeDescriptor<OffsetTime> {
/**
* Singleton access
*/
public static final OffsetTimeJavaDescriptor INSTANCE = new OffsetTimeJavaDescriptor();
@SuppressWarnings("unchecked")
public OffsetTimeJavaDescriptor() {
super( OffsetTime.class, ImmutableMutabilityPlan.INSTANCE );
}
@Override
public String toString(OffsetTime value) {
return OffsetTimeType.FORMATTER.format( value );
}
@Override
public OffsetTime fromString(String string) {
return (OffsetTime) OffsetTimeType.FORMATTER.parse( string );
}
@Override
@SuppressWarnings("unchecked")
public <X> X unwrap(OffsetTime offsetTime, Class<X> type, WrapperOptions options) {
if ( offsetTime == null ) {
return null;
}
if ( OffsetTime.class.isAssignableFrom( type ) ) {
return (X) offsetTime;
}
final ZonedDateTime zonedDateTime = offsetTime.atDate( LocalDate.of( 1970, 1, 1 ) ).toZonedDateTime();
if ( Calendar.class.isAssignableFrom( type ) ) {
return (X) GregorianCalendar.from( zonedDateTime );
}
final Instant instant = zonedDateTime.toInstant();
if ( Timestamp.class.isAssignableFrom( type ) ) {
return (X) Timestamp.from( instant );
}
if ( java.sql.Date.class.isAssignableFrom( type ) ) {
return (X) java.sql.Date.from( instant );
}
if ( java.sql.Time.class.isAssignableFrom( type ) ) {
return (X) java.sql.Time.from( instant );
}
if ( Date.class.isAssignableFrom( type ) ) {
return (X) Date.from( instant );
}
if ( Long.class.isAssignableFrom( type ) ) {
return (X) Long.valueOf( instant.toEpochMilli() );
}
throw unknownUnwrap( type );
}
@Override
public <X> OffsetTime wrap(X value, WrapperOptions options) {
if ( value == null ) {
return null;
}
if ( OffsetTime.class.isInstance( value ) ) {
return (OffsetTime) value;
}
if ( Timestamp.class.isInstance( value ) ) {
final Timestamp ts = (Timestamp) value;
return OffsetTime.ofInstant( ts.toInstant(), ZoneId.systemDefault() );
}
if ( Date.class.isInstance( value ) ) {
final Date date = (Date) value;
return OffsetTime.ofInstant( date.toInstant(), ZoneId.systemDefault() );
}
if ( Long.class.isInstance( value ) ) {
return OffsetTime.ofInstant( Instant.ofEpochMilli( (Long) value ), ZoneId.systemDefault() );
}
if ( Calendar.class.isInstance( value ) ) {
final Calendar calendar = (Calendar) value;
return OffsetTime.ofInstant( calendar.toInstant(), calendar.getTimeZone().toZoneId() );
}
throw unknownWrap( value.getClass() );
}
}

View File

@ -28,6 +28,7 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZonedDateTime;
import java.util.Iterator;
import javax.persistence.Entity;
@ -113,6 +114,7 @@ public class Java8DateTimeTests extends BaseNonConfigCoreFunctionalTestCase {
private Instant instant = Instant.now();
private ZonedDateTime zonedDateTime = ZonedDateTime.now();
private OffsetDateTime offsetDateTime = OffsetDateTime.now();
private OffsetTime offsetTime = OffsetTime.now();
public TheEntity() {
}
@ -177,5 +179,13 @@ public class Java8DateTimeTests extends BaseNonConfigCoreFunctionalTestCase {
public void setOffsetDateTime(OffsetDateTime offsetDateTime) {
this.offsetDateTime = offsetDateTime;
}
public OffsetTime getOffsetTime() {
return offsetTime;
}
public void setOffsetTime(OffsetTime offsetTime) {
this.offsetTime = offsetTime;
}
}
}