From 34f05d183a96234c5a7d3f9558503f71b14474cf Mon Sep 17 00:00:00 2001 From: Gavin Date: Sun, 9 Apr 2023 17:00:17 +0200 Subject: [PATCH] cast DateTimes to Instants and vice versa --- .../hibernate/type/spi/TypeConfiguration.java | 2 ++ .../orm/test/query/hql/FunctionTests.java | 29 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/hibernate-core/src/main/java/org/hibernate/type/spi/TypeConfiguration.java b/hibernate-core/src/main/java/org/hibernate/type/spi/TypeConfiguration.java index 69d33c8a31..6dfe4e04c3 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/spi/TypeConfiguration.java +++ b/hibernate-core/src/main/java/org/hibernate/type/spi/TypeConfiguration.java @@ -14,6 +14,7 @@ import java.math.BigInteger; import java.sql.Time; import java.sql.Timestamp; import java.time.Duration; +import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @@ -340,6 +341,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable { case "biginteger": return getBasicTypeForJavaType( BigInteger.class ); case "bigdecimal": return getBasicTypeForJavaType( BigDecimal.class ); case "duration": return getBasicTypeForJavaType( Duration.class ); + case "instant": return getBasicTypeForJavaType( Instant.class ); case "binary": return getBasicTypeForJavaType( byte[].class ); //this one is very fragile ... works well for BIT or BOOLEAN columns only //works OK, I suppose, for integer columns, but not at all for char columns diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java index e23d509cec..8450bdfe2b 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java @@ -33,6 +33,7 @@ import org.junit.jupiter.api.Test; import java.math.BigDecimal; import java.math.BigInteger; +import java.time.ZoneOffset; import java.util.Date; import java.sql.Time; import java.sql.Timestamp; @@ -864,6 +865,9 @@ public class FunctionTests { assertThat( session.createQuery("select cast(time 12:13:14 as String)", String.class).getSingleResult(), anyOf( is("12:13:14"), is("12:13:14.0000"), is("12.13.14") ) ); assertThat( session.createQuery("select cast(datetime 1911-10-09 12:13:14 as String)", String.class).getSingleResult(), anyOf( startsWith("1911-10-09 12:13:14"), startsWith("1911-10-09-12.13.14") ) ); + assertThat( session.createQuery("select cast(local datetime as Instant)", Instant.class).getSingleResult(), instanceOf(Instant.class) ); + assertThat( session.createQuery("select cast(offset datetime as Instant)", Instant.class).getSingleResult(), instanceOf(Instant.class) ); + assertThat( session.createQuery("select cast(1 as NumericBoolean)", Boolean.class).getSingleResult(), is(true) ); assertThat( session.createQuery("select cast(0 as NumericBoolean)", Boolean.class).getSingleResult(), is(false) ); assertThat( session.createQuery("select cast(true as YesNo)", Boolean.class).getSingleResult(), is(true) ); @@ -1246,6 +1250,31 @@ public class FunctionTests { ); } + @Test + public void testInstantCast(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + Instant instant = Instant.ofEpochSecond(123456789); + assertEquals( instant, + session.createQuery("select cast(?1 as Instant)", Instant.class) + .setParameter( 1, instant.atOffset(ZoneOffset.UTC) ) + .getSingleResult() ); + assertEquals( instant, + session.createQuery("select cast(?1 as Instant)", Instant.class) + .setParameter( 1, instant.atOffset(ZoneOffset.UTC).toLocalDateTime() ) + .getSingleResult() ); + assertEquals( instant.atOffset(ZoneOffset.UTC), + session.createQuery("select cast(?1 as OffsetDateTime)", OffsetDateTime.class) + .setParameter( 1, instant ) + .getSingleResult() ); + assertEquals( instant.atOffset(ZoneOffset.UTC).toLocalDateTime(), + session.createQuery("select cast(?1 as LocalDateTime)", LocalDateTime.class) + .setParameter( 1, instant ) + .getSingleResult() ); + } + ); + } + @Test public void testDurationCast(SessionFactoryScope scope) { scope.inTransaction(