diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverter.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverter.java index 106c002a5..82b62c4d6 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverter.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverter.java @@ -422,7 +422,7 @@ public class MappingJdbcConverter extends MappingRelationalConverter implements @Override public boolean hasValue(RelationalPersistentProperty property) { - if (property.isCollectionLike() || property.isMap()) { + if ((property.isCollectionLike() && property.isEntity())|| property.isMap()) { // attempt relation fetch return true; } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/AbstractJdbcAggregateTemplateIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/AbstractJdbcAggregateTemplateIntegrationTests.java index 0abe37a04..253577a23 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/AbstractJdbcAggregateTemplateIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/AbstractJdbcAggregateTemplateIntegrationTests.java @@ -55,6 +55,7 @@ import org.springframework.data.jdbc.testing.TestDatabaseFeatures; import org.springframework.data.mapping.context.InvalidPersistentPropertyPath; import org.springframework.data.relational.core.conversion.DbActionExecutionException; import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Embedded; import org.springframework.data.relational.core.mapping.InsertOnlyProperty; import org.springframework.data.relational.core.mapping.MappedCollection; import org.springframework.data.relational.core.mapping.RelationalMappingContext; @@ -772,6 +773,36 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests { assertThat(reloaded.digits).isEqualTo(new HashSet<>(asList("one", "two", "three"))); } + @Test //GH-1737 + @EnabledOnFeature(SUPPORTS_ARRAYS) + void saveAndLoadEmbeddedArray() { + + EmbeddedStringListOwner embeddedStringListOwner = new EmbeddedStringListOwner(); + embeddedStringListOwner.embeddedStringList = new EmbeddedStringList(); + embeddedStringListOwner.embeddedStringList.digits = List.of("one", "two", "three"); + + EmbeddedStringListOwner saved = template.save(embeddedStringListOwner); + + EmbeddedStringListOwner reloaded = template.findById(saved.id, EmbeddedStringListOwner.class); + + assertThat(reloaded.embeddedStringList.digits).containsExactly("one", "two", "three"); + } + + @Test //GH-1737 + @EnabledOnFeature(SUPPORTS_ARRAYS) + void saveAndLoadEmptyEmbeddedArray() { + + EmbeddedStringListOwner embeddedStringListOwner = new EmbeddedStringListOwner(); + embeddedStringListOwner.embeddedStringList = new EmbeddedStringList(); + embeddedStringListOwner.embeddedStringList.digits = emptyList(); + + EmbeddedStringListOwner saved = template.save(embeddedStringListOwner); + + EmbeddedStringListOwner reloaded = template.findById(saved.id, EmbeddedStringListOwner.class); + + assertThat(reloaded.embeddedStringList).isNull(); + } + @Test // DATAJDBC-327 void saveAndLoadAnEntityWithByteArray() { @@ -1395,6 +1426,17 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests { List digits = new ArrayList<>(); } + @Table("ARRAY_OWNER") + private static class EmbeddedStringListOwner { + @Id Long id; + + @Embedded(onEmpty = Embedded.OnEmpty.USE_NULL, prefix = "") EmbeddedStringList embeddedStringList; + } + + private static class EmbeddedStringList { + List digits = new ArrayList<>(); + } + static class LegoSet { @Column("id1") diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java index 3469c8b9f..3233d1a27 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java @@ -44,16 +44,7 @@ import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.PersistentPropertyPathAccessor; import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.mapping.model.CachingValueExpressionEvaluatorFactory; -import org.springframework.data.mapping.model.ConvertingPropertyAccessor; -import org.springframework.data.mapping.model.EntityInstantiator; -import org.springframework.data.mapping.model.ParameterValueProvider; -import org.springframework.data.mapping.model.PersistentEntityParameterValueProvider; -import org.springframework.data.mapping.model.PropertyValueProvider; -import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.mapping.model.SpELContext; -import org.springframework.data.mapping.model.ValueExpressionEvaluator; -import org.springframework.data.mapping.model.ValueExpressionParameterValueProvider; +import org.springframework.data.mapping.model.*; import org.springframework.data.projection.EntityProjection; import org.springframework.data.projection.EntityProjectionIntrospector; import org.springframework.data.projection.EntityProjectionIntrospector.ProjectionPredicate; @@ -1168,7 +1159,43 @@ public class MappingRelationalConverter extends AbstractRelationalConverter @Override public boolean hasValue(AggregatePath path) { - return document.get(path.getColumnInfo().alias().getReference()) != null; + Object value = document.get(path.getColumnInfo().alias().getReference()); + + if (value == null) { + return false; + } + if (!path.isCollectionLike()) { + return true; + } + + if (value instanceof char[] ar) { + return ar.length != 0; + } + if (value instanceof byte[] ar) { + return ar.length != 0; + } + if (value instanceof short[] ar) { + return ar.length != 0; + } + if (value instanceof int[] ar) { + return ar.length != 0; + } + if (value instanceof long[] ar) { + return ar.length != 0; + } + if (value instanceof float[] ar) { + return ar.length != 0; + } + if (value instanceof double[] ar) { + return ar.length != 0; + } + if (value instanceof Object[] ar) { + return ar.length != 0; + } + if (value instanceof Collection col) { + return !col.isEmpty(); + } + return true; } @Override