Skip to content

Commit 2f3fb4a

Browse files
christophstroblmp911de
authored andcommitted
Fix NPE in QueryMapper when trying to apply target type on null value.
Closes #3633 Original pull request: #3643.
1 parent 82e05e7 commit 2f3fb4a

File tree

5 files changed

+36
-3
lines changed

5 files changed

+36
-3
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -680,12 +680,12 @@ protected boolean isKeyword(String candidate) {
680680
* converted one by one.
681681
*
682682
* @param documentField the field and its meta data
683-
* @param value the actual value
683+
* @param value the actual value. Can be {@literal null}.
684684
* @return the potentially converted target value.
685685
*/
686-
private Object applyFieldTargetTypeHintToValue(Field documentField, Object value) {
686+
private Object applyFieldTargetTypeHintToValue(Field documentField, @Nullable Object value) {
687687

688-
if (documentField.getProperty() == null || !documentField.getProperty().hasExplicitWriteTarget()) {
688+
if (value == null || documentField.getProperty() == null || !documentField.getProperty().hasExplicitWriteTarget()) {
689689
return value;
690690
}
691691

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java

+11
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,17 @@ void resolvesFieldNameWithUnderscoreOnNestedMappedFieldnameWithUnderscoresCorrec
10821082
.isEqualTo(new org.bson.Document("double_underscore.renamed", new org.bson.Document("$exists", true)));
10831083
}
10841084

1085+
@Test // GH-3633
1086+
void mapsNullValueForFieldWithCustomTargetType() {
1087+
1088+
Query query = query(where("stringAsOid").is(null));
1089+
1090+
org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
1091+
context.getPersistentEntity(NonIdFieldWithObjectIdTargetType.class));
1092+
1093+
assertThat(document).isEqualTo(new org.bson.Document("stringAsOid", null));
1094+
}
1095+
10851096
class WithDeepArrayNesting {
10861097

10871098
List<WithNestedArray> level0;

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java

+12
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@
6060
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
6161
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
6262
import org.springframework.data.mongodb.core.query.BasicQuery;
63+
import org.springframework.data.mongodb.core.query.Criteria;
6364
import org.springframework.data.mongodb.core.query.Query;
65+
import org.springframework.data.mongodb.core.query.Update;
6466
import org.springframework.data.mongodb.repository.Person.Sex;
6567
import org.springframework.data.mongodb.repository.SampleEvaluationContextExtension.SampleSecurityContextHolder;
6668
import org.springframework.data.querydsl.QSort;
@@ -1378,4 +1380,14 @@ void caseInSensitiveInClauseQuotesExpressions() {
13781380
void caseSensitiveInClauseIgnoresExpressions() {
13791381
assertThat(repository.findByFirstnameIn(".*")).isEmpty();
13801382
}
1383+
1384+
@Test // GH-3633
1385+
void annotatedQueryWithNullEqualityCheckShouldWork() {
1386+
1387+
operations.updateFirst(Query.query(Criteria.where("id").is(dave.getId())), Update.update("age", null), Person.class);
1388+
1389+
Person byQueryWithNullEqualityCheck = repository.findByQueryWithNullEqualityCheck();
1390+
assertThat(byQueryWithNullEqualityCheck.getId()).isEqualTo(dave.getId());
1391+
}
1392+
13811393
}

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java

+3
Original file line numberDiff line numberDiff line change
@@ -403,4 +403,7 @@ Page<Person> findByCustomQueryLastnameAndAddressStreetInList(String lastname, Li
403403
Person findPersonByManyArguments(String firstname, String lastname, String email, Integer age, Sex sex,
404404
Date createdAt, List<String> skills, String street, String zipCode, //
405405
String city, UUID uniqueId, String username, String password);
406+
407+
@Query("{ 'age' : null }")
408+
Person findByQueryWithNullEqualityCheck();
406409
}

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReaderUnitTests.java

+7
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,13 @@ void shouldParseNestedArrays() {
383383
.parse("{ 'stores.location' : { $geoWithin: { $centerSphere: [ [ 1.948516, 48.799029 ] , 0.004 ] } } }"));
384384
}
385385

386+
@Test // GH-3633
387+
void parsesNullValue() {
388+
389+
Document target = parse("{ 'parent' : null }");
390+
assertThat(target).isEqualTo(new Document("parent", null));
391+
}
392+
386393
private static Document parse(String json, Object... args) {
387394

388395
ParameterBindingJsonReader reader = new ParameterBindingJsonReader(json, args);

0 commit comments

Comments
 (0)