diff --git a/pom.xml b/pom.xml index 02461b8e40..7de5eb753d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-relational-parent - 3.3.0-SNAPSHOT + 3.3.0-npe-SNAPSHOT pom Spring Data Relational Parent diff --git a/spring-data-jdbc-distribution/pom.xml b/spring-data-jdbc-distribution/pom.xml index 8d987fb028..09ffb728cc 100644 --- a/spring-data-jdbc-distribution/pom.xml +++ b/spring-data-jdbc-distribution/pom.xml @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 3.3.0-SNAPSHOT + 3.3.0-npe-SNAPSHOT ../pom.xml diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml index fddbaab696..d775a343dc 100644 --- a/spring-data-jdbc/pom.xml +++ b/spring-data-jdbc/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-jdbc - 3.3.0-SNAPSHOT + 3.3.0-npe-SNAPSHOT Spring Data JDBC Spring Data module for JDBC repositories. @@ -15,7 +15,7 @@ org.springframework.data spring-data-relational-parent - 3.3.0-SNAPSHOT + 3.3.0-npe-SNAPSHOT diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedIntegrationTests.java index d3c12ea86e..8a7b07c7d4 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedIntegrationTests.java @@ -114,6 +114,21 @@ public void findAllFindsAllEntities() { .containsExactlyInAnyOrder(entity.getId(), other.getId()); } + @Test // GH-1676 + public void findAllFindsAllEntitiesWithOnlyReferenceNotNull() { + + DummyEntity entity = createDummyEntity(); + entity.prefixedEmbeddable.test = null; + entity = repository.save(entity); + DummyEntity other = repository.save(createDummyEntity()); + + Iterable all = repository.findAll(); + + assertThat(all)// + .extracting(DummyEntity::getId)// + .containsExactlyInAnyOrder(entity.getId(), other.getId()); + } + @Test // DATAJDBC-111 public void findByIdReturnsEmptyWhenNoneFound() { diff --git a/spring-data-r2dbc/pom.xml b/spring-data-r2dbc/pom.xml index b6ff5c9a15..3c7e256029 100644 --- a/spring-data-r2dbc/pom.xml +++ b/spring-data-r2dbc/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-r2dbc - 3.3.0-SNAPSHOT + 3.3.0-npe-SNAPSHOT Spring Data R2DBC Spring Data module for R2DBC @@ -15,7 +15,7 @@ org.springframework.data spring-data-relational-parent - 3.3.0-SNAPSHOT + 3.3.0-npe-SNAPSHOT diff --git a/spring-data-relational/pom.xml b/spring-data-relational/pom.xml index 671e71d242..4a31904b2d 100644 --- a/spring-data-relational/pom.xml +++ b/spring-data-relational/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-relational - 3.3.0-SNAPSHOT + 3.3.0-npe-SNAPSHOT Spring Data Relational Spring Data Relational support @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 3.3.0-SNAPSHOT + 3.3.0-npe-SNAPSHOT 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 91da5513f9..55e03c3121 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 @@ -41,16 +41,7 @@ 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.ConvertingPropertyAccessor; -import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator; -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.SpELExpressionEvaluator; -import org.springframework.data.mapping.model.SpELExpressionParameterValueProvider; +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; @@ -307,7 +298,7 @@ protected S read(TypeInformation type, RowDocument source) { * @return the converted object, will never be {@literal null}. */ protected S readAggregate(ConversionContext context, RowDocument document, - TypeInformation typeHint) { + TypeInformation typeHint) { return readAggregate(context, new RowDocumentAccessor(document), typeHint); } @@ -321,7 +312,7 @@ protected S readAggregate(ConversionContext context, RowDocument document, */ @SuppressWarnings("unchecked") protected S readAggregate(ConversionContext context, RowDocumentAccessor documentAccessor, - TypeInformation typeHint) { + TypeInformation typeHint) { Class rawType = typeHint.getType(); @@ -430,8 +421,7 @@ private T doConvert(Object value, Class target) { } @SuppressWarnings("ConstantConditions") - private T doConvert(Object value, Class target, - @Nullable Class fallback) { + private T doConvert(Object value, Class target, @Nullable Class fallback) { if (getConversionService().canConvert(value.getClass(), target) || fallback == null) { return getConversionService().convert(value, target); @@ -504,7 +494,7 @@ public RelationalPropertyValueProvider withContext(ConversionContext context) { entity, contextualizing, context.getPath().getCurrentObject()); return new ConverterAwareSpELExpressionParameterValueProvider(context, evaluator, getConversionService(), - new ConvertingParameterValueProvider<>( parameterProvider::getParameterValue)); + new ConvertingParameterValueProvider<>(parameterProvider::getParameterValue)); } private S populateProperties(ConversionContext context, RelationalPersistentEntity entity, @@ -580,10 +570,19 @@ private boolean shouldReadEmbeddable(ConversionContext context, RelationalPersis for (RelationalPersistentProperty persistentProperty : unwrappedEntity) { - RelationalPropertyValueProvider contextual = propertyValueProvider - .withContext(context.forProperty(persistentProperty)); + ConversionContext nestedContext = context.forProperty(persistentProperty); + RelationalPropertyValueProvider contextual = propertyValueProvider.withContext(nestedContext); - if (contextual.hasValue(persistentProperty)) { + if (persistentProperty.isEmbedded()) { + + RelationalPersistentEntity nestedEntity = getMappingContext() + .getRequiredPersistentEntity(persistentProperty); + + if (shouldReadEmbeddable(nestedContext, persistentProperty, nestedEntity, contextual)) { + return true; + } + + } else if (contextual.hasValue(persistentProperty)) { return true; } } @@ -787,8 +786,7 @@ protected DefaultConversionContext(RelationalConverter sourceConverter, @SuppressWarnings("unchecked") @Override - public S convert(Object source, TypeInformation typeHint, - ConversionContext context) { + public S convert(Object source, TypeInformation typeHint, ConversionContext context) { Assert.notNull(source, "Source must not be null"); Assert.notNull(typeHint, "TypeInformation must not be null"); @@ -1196,7 +1194,7 @@ protected T potentiallyConvertSpelValue(Object object, Parameter (PersistentPropertyAccessor delegate, + private record PropertyTranslatingPropertyAccessor(PersistentPropertyAccessor delegate, PersistentPropertyTranslator propertyTranslator) implements PersistentPropertyAccessor { static PersistentPropertyAccessor create(PersistentPropertyAccessor delegate,