From 83ca6b47394f0773f087a0f199d2cd560bc8f63b Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Thu, 24 Jan 2019 08:50:59 +0100 Subject: [PATCH] DATAJDBC-259 - Reading and writing to SQL array types. Currently works for HsqlDb and Postgres, since the others do not support an array column type. Original pull request: #113. --- .../jdbc/core/DefaultDataAccessStrategy.java | 21 +++- .../data/jdbc/core/EntityRowMapper.java | 2 +- .../jdbc/core/convert/BasicJdbcConverter.java | 16 +++ .../jdbc/core/mapping/JdbcMappingContext.java | 6 +- ...JdbcAggregateTemplateIntegrationTests.java | 114 ++++++++++++++++-- ...AggregateTemplateIntegrationTests-hsql.sql | 2 + ...regateTemplateIntegrationTests-mariadb.sql | 2 +- ...ggregateTemplateIntegrationTests-mssql.sql | 8 +- ...egateTemplateIntegrationTests-postgres.sql | 2 + .../BasicRelationalPersistentProperty.java | 13 +- .../mapping/RelationalPersistentProperty.java | 10 +- ...RelationalPersistentPropertyUnitTests.java | 60 +++++++-- src/main/asciidoc/jdbc.adoc | 2 + 13 files changed, 228 insertions(+), 30 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/DefaultDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/DefaultDataAccessStrategy.java index fa11851fb..b028b53e3 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/DefaultDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/DefaultDataAccessStrategy.java @@ -18,6 +18,8 @@ package org.springframework.data.jdbc.core; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import java.sql.Connection; +import java.sql.JDBCType; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -301,13 +303,30 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy { } else { Object value = propertyAccessor.getProperty(property); - Object convertedValue = converter.writeValue(value, ClassTypeInformation.from(property.getColumnType())); + Object convertedValue = convertForWrite(property, value); + parameters.addValue(prefix + property.getColumnName(), convertedValue, JdbcUtil.sqlTypeFor(property.getColumnType())); } }); return parameters; } + @Nullable + private Object convertForWrite(RelationalPersistentProperty property, @Nullable Object value) { + + Object convertedValue = converter.writeValue(value, ClassTypeInformation.from(property.getColumnType())); + + if (convertedValue == null || !convertedValue.getClass().isArray()) { + return convertedValue; + } + + Class componentType = convertedValue.getClass().getComponentType(); + String typeName = JDBCType.valueOf(JdbcUtil.sqlTypeFor(componentType)).getName(); + + return operations.getJdbcOperations().execute( + (Connection c) -> c.createArrayOf(typeName, (Object[]) convertedValue) + ); + } @SuppressWarnings("unchecked") @Nullable diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/EntityRowMapper.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/EntityRowMapper.java index 0e29305fe..076ad807d 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/EntityRowMapper.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/EntityRowMapper.java @@ -110,7 +110,7 @@ public class EntityRowMapper implements RowMapper { private Object readOrLoadProperty(ResultSet resultSet, @Nullable Object id, RelationalPersistentProperty property, String prefix) { - if (property.isCollectionLike() && id != null) { + if (property.isCollectionOfEntitiesLike() && id != null) { return accessStrategy.findAllByProperty(id, property); } else if (property.isMap() && id != null) { return ITERABLE_OF_ENTRY_TO_MAP_CONVERTER.convert(accessStrategy.findAllByProperty(id, property)); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java index 24f9530f2..99f5b8db2 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java @@ -15,6 +15,9 @@ */ package org.springframework.data.jdbc.core.convert; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.data.convert.CustomConversions; import org.springframework.data.jdbc.core.mapping.AggregateReference; import org.springframework.data.mapping.context.MappingContext; @@ -26,6 +29,9 @@ import org.springframework.data.relational.core.mapping.RelationalPersistentProp import org.springframework.data.util.TypeInformation; import org.springframework.lang.Nullable; +import java.sql.Array; +import java.sql.SQLException; + /** * {@link RelationalConverter} that uses a {@link MappingContext} to apply basic conversion of relational values to * property values. @@ -40,6 +46,8 @@ import org.springframework.lang.Nullable; */ public class BasicJdbcConverter extends BasicRelationalConverter { + private static final Logger LOG = LoggerFactory.getLogger(BasicJdbcConverter.class); + /** * Creates a new {@link BasicRelationalConverter} given {@link MappingContext}. * @@ -85,6 +93,14 @@ public class BasicJdbcConverter extends BasicRelationalConverter { return AggregateReference.to(readValue(value, idType)); } + if (value instanceof Array) { + try { + return readValue(((Array) value).getArray(), type); + } catch (SQLException | ConverterNotFoundException e ) { + LOG.info("Failed to extract a value of type %s from an Array. Attempting to use standard conversions.", e); + } + } + return super.readValue(value, type); } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/JdbcMappingContext.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/JdbcMappingContext.java index d68ad10e8..3229337f0 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/JdbcMappingContext.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/JdbcMappingContext.java @@ -63,6 +63,10 @@ public class JdbcMappingContext extends RelationalMappingContext { @Override protected boolean shouldCreatePersistentEntityFor(TypeInformation type) { - return super.shouldCreatePersistentEntityFor(type) && !AggregateReference.class.isAssignableFrom(type.getType()); + + return super.shouldCreatePersistentEntityFor(type) // + && !AggregateReference.class.isAssignableFrom(type.getType()) // + && !type.isCollectionLike(); } + } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java index 91784033b..f5dfce852 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java @@ -21,9 +21,13 @@ import static org.assertj.core.api.Assertions.*; import lombok.Data; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.assertj.core.api.SoftAssertions; +import org.junit.Assume; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; @@ -38,8 +42,10 @@ import org.springframework.data.jdbc.testing.TestConfiguration; import org.springframework.data.relational.core.conversion.RelationalConverter; import org.springframework.data.relational.core.mapping.Column; import org.springframework.data.relational.core.mapping.RelationalMappingContext; +import org.springframework.data.relational.core.mapping.Table; import org.springframework.test.annotation.IfProfileValue; import org.springframework.test.annotation.ProfileValueSourceConfiguration; +import org.springframework.test.annotation.ProfileValueUtils; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.rules.SpringClassRule; import org.springframework.test.context.junit4.rules.SpringMethodRule; @@ -318,6 +324,102 @@ public class JdbcAggregateTemplateIntegrationTests { assertThat(reloaded.content).extracting(e -> e.content).containsExactly("content"); } + @Test // DATAJDBC-259 + public void saveAndLoadAnEntityWithArray() { + + // MySQL and other do not support array datatypes. See + // https://dev.mysql.com/doc/refman/8.0/en/data-type-overview.html + assumeNot("mysql"); + assumeNot("mariadb"); + assumeNot("mssql"); + + ArrayOwner arrayOwner = new ArrayOwner(); + arrayOwner.digits = new String[] { "one", "two", "three" }; + + ArrayOwner saved = template.save(arrayOwner); + + assertThat(saved.id).isNotNull(); + + ArrayOwner reloaded = template.findById(saved.id, ArrayOwner.class); + + assertThat(reloaded).isNotNull(); + assertThat(reloaded.id).isEqualTo(saved.id); + assertThat(reloaded.digits).isEqualTo(new String[] { "one", "two", "three" }); + } + + @Test // DATAJDBC-259 + public void saveAndLoadAnEntityWithList() { + + // MySQL and others do not support array datatypes. See + // https://dev.mysql.com/doc/refman/8.0/en/data-type-overview.html + assumeNot("mysql"); + assumeNot("mariadb"); + assumeNot("mssql"); + + ListOwner arrayOwner = new ListOwner(); + arrayOwner.digits.addAll(Arrays.asList("one", "two", "three")); + + ListOwner saved = template.save(arrayOwner); + + assertThat(saved.id).isNotNull(); + + ListOwner reloaded = template.findById(saved.id, ListOwner.class); + + assertThat(reloaded).isNotNull(); + assertThat(reloaded.id).isEqualTo(saved.id); + assertThat(reloaded.digits).isEqualTo(Arrays.asList("one", "two", "three")); + } + + @Test // DATAJDBC-259 + public void saveAndLoadAnEntityWithSet() { + + // MySQL and others do not support array datatypes. See + // https://dev.mysql.com/doc/refman/8.0/en/data-type-overview.html + assumeNot("mysql"); + assumeNot("mariadb"); + assumeNot("mssql"); + + SetOwner setOwner = new SetOwner(); + setOwner.digits.addAll(Arrays.asList("one", "two", "three")); + + SetOwner saved = template.save(setOwner); + + assertThat(saved.id).isNotNull(); + + SetOwner reloaded = template.findById(saved.id, SetOwner.class); + + assertThat(reloaded).isNotNull(); + assertThat(reloaded.id).isEqualTo(saved.id); + assertThat(reloaded.digits).isEqualTo(new HashSet<>(Arrays.asList("one", "two", "three"))); + } + + private static void assumeNot(String dbProfileName) { + + Assume.assumeTrue("true" + .equalsIgnoreCase(ProfileValueUtils.retrieveProfileValueSource(JdbcAggregateTemplateIntegrationTests.class) + .get("current.database.is.not." + dbProfileName))); + } + + private static class ArrayOwner { + @Id Long id; + + String[] digits; + } + + @Table("ARRAY_OWNER") + private static class ListOwner { + @Id Long id; + + List digits = new ArrayList<>(); + } + + @Table("ARRAY_OWNER") + private static class SetOwner { + @Id Long id; + + Set digits = new HashSet<>(); + } + private static LegoSet createLegoSet() { LegoSet entity = new LegoSet(); @@ -333,8 +435,7 @@ public class JdbcAggregateTemplateIntegrationTests { @Data static class LegoSet { - @Column("id1") - @Id private Long id; + @Column("id1") @Id private Long id; private String name; @@ -345,16 +446,14 @@ public class JdbcAggregateTemplateIntegrationTests { @Data static class Manual { - @Column("id2") - @Id private Long id; + @Column("id2") @Id private Long id; private String content; } static class OneToOneParent { - @Column("id3") - @Id private Long id; + @Column("id3") @Id private Long id; private String content; private ChildNoId child; @@ -366,8 +465,7 @@ public class JdbcAggregateTemplateIntegrationTests { static class ListParent { - @Column("id4") - @Id private Long id; + @Column("id4") @Id private Long id; String name; List content = new ArrayList<>(); } diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-hsql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-hsql.sql index 6354676d1..2bfce4d2d 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-hsql.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-hsql.sql @@ -9,3 +9,5 @@ CREATE TABLE Child_No_Id (ONE_TO_ONE_PARENT INTEGER PRIMARY KEY, content VARCHAR CREATE TABLE LIST_PARENT ( id4 BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, NAME VARCHAR(100)); CREATE TABLE element_no_id ( content VARCHAR(100), LIST_PARENT_key BIGINT, LIST_PARENT BIGINT); + +CREATE TABLE ARRAY_OWNER (ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY, DIGITS VARCHAR(20) ARRAY[10] NOT NULL); \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-mariadb.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-mariadb.sql index 07ecf86ba..8b739ea10 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-mariadb.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-mariadb.sql @@ -8,4 +8,4 @@ CREATE TABLE ONE_TO_ONE_PARENT ( id3 BIGINT AUTO_INCREMENT PRIMARY KEY, content CREATE TABLE Child_No_Id (ONE_TO_ONE_PARENT INTEGER PRIMARY KEY, content VARCHAR(30)); CREATE TABLE LIST_PARENT ( id4 BIGINT AUTO_INCREMENT PRIMARY KEY, NAME VARCHAR(100)); -CREATE TABLE element_no_id ( content VARCHAR(100), LIST_PARENT_key BIGINT, LIST_PARENT BIGINT); +CREATE TABLE element_no_id ( content VARCHAR(100), LIST_PARENT_key BIGINT, LIST_PARENT BIGINT); \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-mssql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-mssql.sql index bae84431b..764f92436 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-mssql.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-mssql.sql @@ -1,15 +1,15 @@ -DROP TABLE IF EXISTS LEGO_SET; DROP TABLE IF EXISTS MANUAL; +DROP TABLE IF EXISTS LEGO_SET; CREATE TABLE LEGO_SET ( id1 BIGINT IDENTITY PRIMARY KEY, NAME VARCHAR(30)); CREATE TABLE MANUAL ( id2 BIGINT IDENTITY PRIMARY KEY, LEGO_SET BIGINT, ALTERNATIVE BIGINT, CONTENT VARCHAR(2000)); ALTER TABLE MANUAL ADD FOREIGN KEY (LEGO_SET) REFERENCES LEGO_SET(id1); -DROP TABLE IF EXISTS ONE_TO_ONE_PARENT; DROP TABLE IF EXISTS Child_No_Id; +DROP TABLE IF EXISTS ONE_TO_ONE_PARENT; CREATE TABLE ONE_TO_ONE_PARENT ( id3 BIGINT IDENTITY PRIMARY KEY, content VARCHAR(30)); CREATE TABLE Child_No_Id (ONE_TO_ONE_PARENT BIGINT PRIMARY KEY, content VARCHAR(30)); -DROP TABLE IF EXISTS LIST_PARENT; DROP TABLE IF EXISTS element_no_id; +DROP TABLE IF EXISTS LIST_PARENT; CREATE TABLE LIST_PARENT ( id4 BIGINT IDENTITY PRIMARY KEY, NAME VARCHAR(100)); -CREATE TABLE element_no_id ( content VARCHAR(100), LIST_PARENT_key BIGINT, LIST_PARENT BIGINT); +CREATE TABLE element_no_id ( content VARCHAR(100), LIST_PARENT_key BIGINT, LIST_PARENT BIGINT); \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql index 575111921..f7fa03f5f 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql @@ -12,3 +12,5 @@ CREATE TABLE Child_No_Id (ONE_TO_ONE_PARENT INTEGER PRIMARY KEY, content VARCHAR CREATE TABLE LIST_PARENT ( id4 SERIAL PRIMARY KEY, NAME VARCHAR(100)); CREATE TABLE element_no_id ( content VARCHAR(100), LIST_PARENT_key BIGINT, LIST_PARENT INTEGER); + +CREATE TABLE ARRAY_OWNER (ID SERIAL PRIMARY KEY, DIGITS VARCHAR(20) ARRAY[10] NOT NULL); \ No newline at end of file diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentProperty.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentProperty.java index cd16d16c8..3223ce8d6 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentProperty.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentProperty.java @@ -15,6 +15,7 @@ */ package org.springframework.data.relational.core.mapping; +import java.lang.reflect.Array; import java.time.ZonedDateTime; import java.time.temporal.Temporal; import java.util.Date; @@ -139,7 +140,17 @@ public class BasicRelationalPersistentProperty extends AnnotationBasedPersistent Class columnType = columnTypeIfEntity(getActualType()); - return columnType == null ? columnTypeForNonEntity(getActualType()) : columnType; + if (columnType != null) { + return columnType; + } + + Class componentColumnType = columnTypeForNonEntity(getActualType()); + + if (isCollectionOfSimpleTypeLike()) { + return Array.newInstance(componentColumnType, 0).getClass(); + } + + return componentColumnType; } @Override diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentProperty.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentProperty.java index 1040eed89..f6352b5bd 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentProperty.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentProperty.java @@ -45,7 +45,7 @@ public interface RelationalPersistentProperty extends PersistentProperty persistentEntity = context.getRequiredPersistentEntity(DummyEntity.class); - - checkTargetType(softly, persistentEntity, "someEnum", String.class); - checkTargetType(softly, persistentEntity, "localDateTime", Date.class); - checkTargetType(softly, persistentEntity, "zonedDateTime", String.class); - checkTargetType(softly, persistentEntity, "uuid", UUID.class); + checkTargetType(softly, entity, "someEnum", String.class); + checkTargetType(softly, entity, "localDateTime", Date.class); + checkTargetType(softly, entity, "zonedDateTime", String.class); + checkTargetType(softly, entity, "uuid", UUID.class); softly.assertAll(); } @@ -83,8 +81,6 @@ public class BasicRelationalPersistentPropertyUnitTests { @Test // DATAJDBC-106 public void detectsAnnotatedColumnName() { - RelationalPersistentEntity entity = context.getRequiredPersistentEntity(DummyEntity.class); - assertThat(entity.getRequiredPersistentProperty("name").getColumnName()).isEqualTo("dummy_name"); assertThat(entity.getRequiredPersistentProperty("localDateTime").getColumnName()) .isEqualTo("dummy_last_updated_at"); @@ -93,9 +89,7 @@ public class BasicRelationalPersistentPropertyUnitTests { @Test // DATAJDBC-218 public void detectsAnnotatedColumnAndKeyName() { - RelationalPersistentProperty listProperty = context // - .getRequiredPersistentEntity(DummyEntity.class) // - .getRequiredPersistentProperty("someList"); + RelationalPersistentProperty listProperty = entity.getRequiredPersistentProperty("someList"); assertThat(listProperty.getReverseColumnName()).isEqualTo("dummy_column_name"); assertThat(listProperty.getKeyColumn()).isEqualTo("dummy_key_column_name"); @@ -130,6 +124,40 @@ public class BasicRelationalPersistentPropertyUnitTests { softly.assertAll(); } + @Test // DATAJDBC-259 + public void classificationOfCollectionLikeProperties() { + + RelationalPersistentProperty listOfString = entity.getRequiredPersistentProperty("listOfString"); + RelationalPersistentProperty arrayOfString = entity.getRequiredPersistentProperty("arrayOfString"); + RelationalPersistentProperty listOfEntity = entity.getRequiredPersistentProperty("listOfEntity"); + RelationalPersistentProperty arrayOfEntity = entity.getRequiredPersistentProperty("arrayOfEntity"); + + SoftAssertions softly = new SoftAssertions(); + + softly.assertThat(listOfString.isCollectionOfSimpleTypeLike()) + .describedAs("listOfString is a Collection of a simple type.").isEqualTo(true); + softly.assertThat(arrayOfString.isCollectionOfSimpleTypeLike()) + .describedAs("arrayOfString is a Collection of a simple type.").isTrue(); + softly.assertThat(listOfEntity.isCollectionOfSimpleTypeLike()) + .describedAs("listOfEntity is a Collection of a simple type.").isFalse(); + softly.assertThat(arrayOfEntity.isCollectionOfSimpleTypeLike()) + .describedAs("arrayOfEntity is a Collection of a simple type.").isFalse(); + + BiConsumer checkEitherOr = (p, s) -> softly + .assertThat(p.isCollectionOfSimpleTypeLike()).describedAs(s + " contains either simple types or entities") + .isNotEqualTo(p.isCollectionOfEntitiesLike()); + + checkEitherOr.accept(listOfString,"listOfString"); + checkEitherOr.accept(arrayOfString,"arrayOfString"); + checkEitherOr.accept(listOfEntity,"listOfEntity"); + checkEitherOr.accept(arrayOfEntity,"arrayOfEntity"); + + softly.assertThat(arrayOfString.getColumnType()).isEqualTo(String[].class); + softly.assertThat(listOfString.getColumnType()).isEqualTo(String[].class); + + softly.assertAll(); + } + private void checkTargetType(SoftAssertions softly, RelationalPersistentEntity persistentEntity, String propertyName, Class expected) { @@ -146,9 +174,14 @@ public class BasicRelationalPersistentPropertyUnitTests { private final SomeEnum someEnum; private final LocalDateTime localDateTime; private final ZonedDateTime zonedDateTime; - private final List listField; private final UUID uuid; + // DATAJDBC-259 + private final List listOfString; + private final String[] arrayOfString; + private final List listOfEntity; + private final OtherEntity[] arrayOfEntity; + @Column(value = "dummy_column_name", keyColumn = "dummy_key_column_name") private List someList; // DATACMNS-106 @@ -184,4 +217,7 @@ public class BasicRelationalPersistentPropertyUnitTests { private static class EmbeddableEntity { private final String embeddedTest; } + + @SuppressWarnings("unused") + private static class OtherEntity {} } diff --git a/src/main/asciidoc/jdbc.adoc b/src/main/asciidoc/jdbc.adoc index 880356c66..8796935cf 100644 --- a/src/main/asciidoc/jdbc.adoc +++ b/src/main/asciidoc/jdbc.adoc @@ -118,6 +118,8 @@ The properties of the following types are currently supported: * `java.util.Date`, `java.time.LocalDate`, `java.time.LocalDateTime`, and `java.time.LocalTime` +* Arrays and Collections of the types mentioned above can be mapped to columns of array type if your database supports that. + * Anything your database driver accepts. * References to other entities. They are considered a one-to-one relationship, or an embedded type.