Browse Source

Refine embeddable emptiness checks to consider whether the collection holds entities.

Embedded entities which contain a empty collection of values that aren't entities are now considered empty, if this collection is empty.

Closes #1737
Original pull request: #1812
pull/1816/head
Jens Schauder 2 years ago committed by Mark Paluch
parent
commit
0a1bb2b48d
No known key found for this signature in database
GPG Key ID: 55BC6374BAA9D973
  1. 2
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverter.java
  2. 42
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/AbstractJdbcAggregateTemplateIntegrationTests.java
  3. 49
      spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java

2
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverter.java

@ -422,7 +422,7 @@ public class MappingJdbcConverter extends MappingRelationalConverter implements @@ -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;
}

42
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/AbstractJdbcAggregateTemplateIntegrationTests.java

@ -55,6 +55,7 @@ import org.springframework.data.jdbc.testing.TestDatabaseFeatures; @@ -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 { @@ -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 { @@ -1395,6 +1426,17 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
List<Float> 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<String> digits = new ArrayList<>();
}
static class LegoSet {
@Column("id1")

49
spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java

@ -44,16 +44,7 @@ import org.springframework.data.mapping.PersistentProperty; @@ -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 @@ -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

Loading…
Cancel
Save