diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/ArrayJdbcType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/ArrayJdbcType.java index 8af039fed718..6f1d3fc74f63 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/ArrayJdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/ArrayJdbcType.java @@ -119,10 +119,19 @@ protected String getElementTypeName(JavaType javaType, SharedSessionContractI final String typeName = ddlTypeRegistry.getDescriptor( elementJdbcType.getDdlTypeCode() ) .getTypeName( size, new BasicTypeImpl<>( elementJavaType, elementJdbcType), ddlTypeRegistry ); - // getTypeName for this case required length, etc, parameters. - // Cut them out and use database defaults. - final int cutIndex = typeName.indexOf( '(' ); - return cutIndex > 0 ? typeName.substring( 0, cutIndex ) : typeName; + + final int cutIndexBegin = typeName.indexOf( '(' ); + if ( cutIndexBegin > 0 ) { + final int cutIndexEnd = typeName.lastIndexOf( ')' ); + assert cutIndexEnd > cutIndexBegin; + // getTypeName for this case required length, etc, parameters. + // Cut them out and use database defaults. + // e.g. "timestamp($p) with timezone" becomes "timestamp with timezone" + return typeName.substring( 0, cutIndexBegin ) + typeName.substring( cutIndexEnd + 1 ); + } + else { + return typeName; + } } protected Object[] getArray(BasicBinder binder, ValueBinder elementBinder, T value, WrapperOptions options) diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/javatime/GlobalJavaTimeJdbcTypeTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/javatime/GlobalJavaTimeJdbcTypeTests.java index 26a874c1629a..cfac2732f234 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/javatime/GlobalJavaTimeJdbcTypeTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/javatime/GlobalJavaTimeJdbcTypeTests.java @@ -8,6 +8,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.OffsetDateTime; import java.time.temporal.ChronoUnit; import org.hibernate.cfg.MappingSettings; @@ -17,6 +18,7 @@ import org.hibernate.dialect.Dialect; import org.hibernate.dialect.HANADialect; import org.hibernate.dialect.OracleDialect; +import org.hibernate.dialect.PostgreSQLDialect; import org.hibernate.dialect.SybaseDialect; import org.hibernate.mapping.BasicValue; import org.hibernate.mapping.PersistentClass; @@ -29,6 +31,7 @@ import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModelScope; +import org.hibernate.testing.orm.junit.RequiresDialect; import org.hibernate.testing.orm.junit.ServiceRegistry; import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactoryScope; @@ -203,6 +206,23 @@ void testLocalTime(SessionFactoryScope scope) { } ); } + @Test + @RequiresDialect(value = PostgreSQLDialect.class) + void testArray(SessionFactoryScope scope) { + final var offsetDateTime = OffsetDateTime.parse("1977-07-24T12:34:56+02:00"); + scope.inTransaction( session -> { + final var nativeQuery = session.createNativeQuery( + "WITH data AS (SELECT unnest(?) AS id, unnest(?) AS offset_date_time)" + + " INSERT INTO EntityWithJavaTimeValues (id, theOffsetDateTime) SELECT * FROM data" + ); + nativeQuery.setParameter( 1, new int[] { 1 } ); + nativeQuery.setParameter( 2, new OffsetDateTime[] { offsetDateTime } ); + assertThat( nativeQuery.executeUpdate() ).isEqualTo( 1 ); + final var found = session.find( EntityWithJavaTimeValues.class, 1 ); + assertThat( found.theOffsetDateTime.toInstant() ).isEqualTo( offsetDateTime.toInstant() ); + } ); + } + @AfterEach void dropTestData(SessionFactoryScope scope) { scope.getSessionFactory().getSchemaManager().truncate(); @@ -215,6 +235,8 @@ public static class EntityWithJavaTimeValues { private Integer id; private String name; + private OffsetDateTime theOffsetDateTime; + private Instant theInstant; private LocalDateTime theLocalDateTime;