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 84b7be319856..3a93f793a984 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 @@ -130,11 +130,13 @@ protected String getElementTypeName(JavaType javaType, SharedSessionContractI final DdlTypeRegistry ddlTypeRegistry = session.getTypeConfiguration().getDdlTypeRegistry(); final String typeName = ddlTypeRegistry.getDescriptor( elementJdbcType.getDdlTypeCode() ) .getTypeName( size, new BasicTypeImpl<>( elementJavaType, elementJdbcType), ddlTypeRegistry ); - int cutIndex = typeName.indexOf( '(' ); - if ( cutIndex > 0 ) { + int cutIndexBegin = typeName.indexOf( '(' ); + int cutIndexEnd = typeName.lastIndexOf( ')' ); + if ( cutIndexBegin > 0 && cutIndexEnd > cutIndexBegin ) { // getTypeName for this case required length, etc, parameters. // Cut them out and use database defaults. - return typeName.substring( 0, cutIndex ); + // e.g. "timestamp($p) with timezone" becomes "timestamp with timezone" + return typeName.substring( 0, cutIndexBegin ) + typeName.substring( cutIndexEnd + 1 ); } else { return typeName; 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 5e1b6e95e51a..48876351a4e5 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 @@ -10,6 +10,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; @@ -19,6 +20,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; @@ -31,6 +33,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; @@ -204,6 +207,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.inTransaction( (session) -> { @@ -218,6 +238,8 @@ public static class EntityWithJavaTimeValues { private Integer id; private String name; + private OffsetDateTime theOffsetDateTime; + private Instant theInstant; private LocalDateTime theLocalDateTime;