diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java index 8d86b8899..4fca31ed4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java @@ -680,12 +680,12 @@ public class QueryMapper { * converted one by one. * * @param documentField the field and its meta data - * @param value the actual value + * @param value the actual value. Can be {@literal null}. * @return the potentially converted target value. */ - private Object applyFieldTargetTypeHintToValue(Field documentField, Object value) { + private Object applyFieldTargetTypeHintToValue(Field documentField, @Nullable Object value) { - if (documentField.getProperty() == null || !documentField.getProperty().hasExplicitWriteTarget()) { + if (value == null || documentField.getProperty() == null || !documentField.getProperty().hasExplicitWriteTarget()) { return value; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java index d6e325e8f..00f4b2eb5 100755 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java @@ -1082,6 +1082,17 @@ public class QueryMapperUnitTests { .isEqualTo(new org.bson.Document("double_underscore.renamed", new org.bson.Document("$exists", true))); } + @Test // GH-3633 + void mapsNullValueForFieldWithCustomTargetType() { + + Query query = query(where("stringAsOid").is(null)); + + org.bson.Document document = mapper.getMappedObject(query.getQueryObject(), + context.getPersistentEntity(NonIdFieldWithObjectIdTargetType.class)); + + assertThat(document).isEqualTo(new org.bson.Document("stringAsOid", null)); + } + class WithDeepArrayNesting { List level0; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java index 841d4706a..fea7e400f 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java @@ -60,7 +60,9 @@ import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.aggregation.AggregationResults; import org.springframework.data.mongodb.core.geo.GeoJsonPoint; import org.springframework.data.mongodb.core.query.BasicQuery; +import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; +import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.repository.Person.Sex; import org.springframework.data.mongodb.repository.SampleEvaluationContextExtension.SampleSecurityContextHolder; import org.springframework.data.querydsl.QSort; @@ -1378,4 +1380,14 @@ public abstract class AbstractPersonRepositoryIntegrationTests { void caseSensitiveInClauseIgnoresExpressions() { assertThat(repository.findByFirstnameIn(".*")).isEmpty(); } + + @Test // GH-3633 + void annotatedQueryWithNullEqualityCheckShouldWork() { + + operations.updateFirst(Query.query(Criteria.where("id").is(dave.getId())), Update.update("age", null), Person.class); + + Person byQueryWithNullEqualityCheck = repository.findByQueryWithNullEqualityCheck(); + assertThat(byQueryWithNullEqualityCheck.getId()).isEqualTo(dave.getId()); + } + } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java index e58d258f4..bce0aec99 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java @@ -403,4 +403,7 @@ public interface PersonRepository extends MongoRepository, Query Person findPersonByManyArguments(String firstname, String lastname, String email, Integer age, Sex sex, Date createdAt, List skills, String street, String zipCode, // String city, UUID uniqueId, String username, String password); + + @Query("{ 'age' : null }") + Person findByQueryWithNullEqualityCheck(); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReaderUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReaderUnitTests.java index 72ab2b454..1a684af16 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReaderUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReaderUnitTests.java @@ -383,6 +383,13 @@ class ParameterBindingJsonReaderUnitTests { .parse("{ 'stores.location' : { $geoWithin: { $centerSphere: [ [ 1.948516, 48.799029 ] , 0.004 ] } } }")); } + @Test // GH-3633 + void parsesNullValue() { + + Document target = parse("{ 'parent' : null }"); + assertThat(target).isEqualTo(new Document("parent", null)); + } + private static Document parse(String json, Object... args) { ParameterBindingJsonReader reader = new ParameterBindingJsonReader(json, args);