From 97f94776839a04007c67bfe6ccba80c007545b52 Mon Sep 17 00:00:00 2001 From: Marco Belladelli Date: Thu, 19 Sep 2024 10:44:23 +0200 Subject: [PATCH 1/2] HHH-18582 Add test for issue --- .../test/mapping/array/ArrayOfArraysTest.java | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/mapping/array/ArrayOfArraysTest.java diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/array/ArrayOfArraysTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/array/ArrayOfArraysTest.java new file mode 100644 index 000000000000..755cd13700ea --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/array/ArrayOfArraysTest.java @@ -0,0 +1,95 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-or-later + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.mapping.array; + +import org.hibernate.MappingException; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.cfg.Configuration; +import org.hibernate.type.SqlTypes; + +import org.hibernate.testing.orm.junit.DialectFeatureChecks; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.RequiresDialectFeature; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.hibernate.testing.orm.junit.Setting; +import org.junit.jupiter.api.Test; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import org.assertj.core.data.Index; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +/** + * @author Marco Belladelli + */ +@RequiresDialectFeature( feature = DialectFeatureChecks.SupportsStandardArrays.class ) +public class ArrayOfArraysTest { + @DomainModel( annotatedClasses = ArrayOfArraysTest.EntityWithDoubleByteArray.class ) + @SessionFactory + @ServiceRegistry( settings = @Setting( name = AvailableSettings.HBM2DDL_AUTO, value = "create-drop" ) ) + @Test + public void testDoubleByteArrayWorks(SessionFactoryScope scope) { + final Long id = scope.fromTransaction( session -> { + final EntityWithDoubleByteArray entity = new EntityWithDoubleByteArray(); + entity.setByteArray( new byte[][] { new byte[] { 1 } } ); + session.persist( entity ); + return entity.getId(); + } ); + scope.inSession( session -> { + final byte[][] byteArray = session.find( EntityWithDoubleByteArray.class, id ).getByteArray(); + assertThat( byteArray ).hasDimensions( 1, 1 ).contains( new byte[] { 1 }, Index.atIndex( 0 ) ); + } ); + } + + @Test + public void testDoubleIntegerArrayThrows() { + final Configuration cfg = new Configuration(); + cfg.addAnnotatedClass( EntityWithDoubleIntegerArray.class ); + try (final org.hibernate.SessionFactory sf = cfg.buildSessionFactory()) { + fail( "Expecting Integer[][] to trigger exception as non-byte multidimensional arrays are not supported" ); + } + catch (Exception e) { + assertThat( e ).isInstanceOf( MappingException.class ).hasMessage( "Nested arrays (with the exception of byte[][]) are not supported" ); + } + } + + @Entity( name = "EntityWithDoubleByteArray" ) + static class EntityWithDoubleByteArray { + @Id + @GeneratedValue + private Long id; + + @JdbcTypeCode( SqlTypes.ARRAY ) + private byte[][] byteArray; + + public Long getId() { + return id; + } + + public byte[][] getByteArray() { + return byteArray; + } + + public void setByteArray(byte[][] byteArray) { + this.byteArray = byteArray; + } + } + + @Entity( name = "EntityWithDoubleIntegerArray" ) + static class EntityWithDoubleIntegerArray { + @Id + @GeneratedValue + private Long id; + + @JdbcTypeCode( SqlTypes.ARRAY ) + private Integer[][] integers; + } +} From a1010b818959b4dfbb46cb45123036ff5b8175eb Mon Sep 17 00:00:00 2001 From: Marco Belladelli Date: Thu, 19 Sep 2024 10:44:49 +0200 Subject: [PATCH 2/2] HHH-18582 Throw explicit error when trying to map nested arrays --- .../java/org/hibernate/type/BasicTypeRegistry.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java b/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java index ae308bf8fd2d..c6f7c197bb09 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java +++ b/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java @@ -11,6 +11,7 @@ import org.hibernate.HibernateException; import org.hibernate.Internal; +import org.hibernate.MappingException; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.StringHelper; @@ -156,16 +157,24 @@ private BasicType resolvedType(JavaType javaType, JdbcType jdbcType) { } private BasicType resolvedType(ArrayJdbcType arrayType, BasicPluralJavaType castPluralJavaType) { + final BasicType elementType = resolve( castPluralJavaType.getElementJavaType(), arrayType.getElementJdbcType() ); final BasicType resolvedType = castPluralJavaType.resolveType( typeConfiguration, typeConfiguration.getCurrentBaseSqlTypeIndicators().getDialect(), - resolve( castPluralJavaType.getElementJavaType(), arrayType.getElementJdbcType() ), + elementType, null, typeConfiguration.getCurrentBaseSqlTypeIndicators() ); if ( resolvedType instanceof BasicPluralType ) { register( resolvedType ); } + else if ( resolvedType == null ) { + final Class elementJavaTypeClass = elementType.getJavaTypeDescriptor().getJavaTypeClass(); + if ( elementJavaTypeClass != null && elementJavaTypeClass.isArray() && elementJavaTypeClass != byte[].class ) { + // No support for nested arrays, except for byte[][] + throw new MappingException( "Nested arrays (with the exception of byte[][]) are not supported" ); + } + } return resolvedType; }