Skip to content

Commit 3224fa8

Browse files
christophstroblodrotbohm
authored andcommitted
DATAMONGO-1251 - Fixed potential NullPointerException in UpdateMapper.
We now explicitly handle the possibility of the source object a type hint needs to be calculated for being null.
1 parent ce156c1 commit 3224fa8

File tree

2 files changed

+74
-5
lines changed

2 files changed

+74
-5
lines changed

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

+4-5
Original file line numberDiff line numberDiff line change
@@ -142,19 +142,18 @@ private DBObject getMappedValue(Field field, Modifier modifier) {
142142
}
143143

144144
private TypeInformation<?> getTypeHintForEntity(Object source, MongoPersistentEntity<?> entity) {
145-
return processTypeHintForNestedDocuments(source, entity.getTypeInformation());
146-
}
147-
148-
private TypeInformation<?> processTypeHintForNestedDocuments(Object source, TypeInformation<?> info) {
149145

146+
TypeInformation<?> info = entity.getTypeInformation();
150147
Class<?> type = info.getActualType().getType();
151-
if (type.isInterface() || java.lang.reflect.Modifier.isAbstract(type.getModifiers())) {
148+
149+
if (source == null || type.isInterface() || java.lang.reflect.Modifier.isAbstract(type.getModifiers())) {
152150
return info;
153151
}
154152

155153
if (!type.equals(source.getClass())) {
156154
return info;
157155
}
156+
158157
return NESTED_DOCUMENT;
159158
}
160159

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

+70
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import static org.springframework.data.mongodb.core.DBObjectTestUtils.*;
2323
import static org.springframework.data.mongodb.test.util.IsBsonObject.*;
2424

25+
import java.time.LocalDate;
2526
import java.util.Arrays;
2627
import java.util.Collections;
2728
import java.util.List;
@@ -792,6 +793,70 @@ public void mapsUpdateWithBothReadingAndWritingConverterRegistered() {
792793
assertThat(result, isBsonObject().containing("$set.allocation", Allocation.AVAILABLE.code));
793794
}
794795

796+
/**
797+
* see DATAMONGO-1251
798+
*/
799+
@Test
800+
public void mapsNullValueCorrectlyForSimpleTypes() {
801+
802+
Update update = new Update().set("value", null);
803+
804+
DBObject mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
805+
context.getPersistentEntity(ConcreteChildClass.class));
806+
807+
DBObject $set = DBObjectTestUtils.getAsDBObject(mappedUpdate, "$set");
808+
assertThat($set.containsField("value"), is(true));
809+
assertThat($set.get("value"), nullValue());
810+
}
811+
812+
/**
813+
* see DATAMONGO-1251
814+
*/
815+
@Test
816+
public void mapsNullValueCorrectlyForJava8Date() {
817+
818+
Update update = new Update().set("date", null);
819+
820+
DBObject mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
821+
context.getPersistentEntity(ClassWithJava8Date.class));
822+
823+
DBObject $set = DBObjectTestUtils.getAsDBObject(mappedUpdate, "$set");
824+
assertThat($set.containsField("date"), is(true));
825+
assertThat($set.get("value"), nullValue());
826+
}
827+
828+
/**
829+
* see DATAMONGO-1251
830+
*/
831+
@Test
832+
public void mapsNullValueCorrectlyForCollectionTypes() {
833+
834+
Update update = new Update().set("values", null);
835+
836+
DBObject mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
837+
context.getPersistentEntity(ListModel.class));
838+
839+
DBObject $set = DBObjectTestUtils.getAsDBObject(mappedUpdate, "$set");
840+
assertThat($set.containsField("values"), is(true));
841+
assertThat($set.get("value"), nullValue());
842+
}
843+
844+
/**
845+
* see DATAMONGO-1251
846+
*/
847+
@Test
848+
public void mapsNullValueCorrectlyForPropertyOfNestedDocument() {
849+
850+
Update update = new Update().set("concreteValue.name", null);
851+
852+
DBObject mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
853+
context.getPersistentEntity(EntityWithObject.class));
854+
855+
DBObject $set = DBObjectTestUtils.getAsDBObject(mappedUpdate, "$set");
856+
assertThat($set.containsField("concreteValue.name"), is(true));
857+
assertThat($set.get("concreteValue.name"), nullValue());
858+
}
859+
795860
static class DomainTypeWrappingConcreteyTypeHavingListOfInterfaceTypeAttributes {
796861
ListModelWrapper concreteTypeWithListAttributeOfInterfaceType;
797862
}
@@ -1061,4 +1126,9 @@ public Allocation convert(String source) {
10611126
}
10621127
}
10631128
}
1129+
1130+
static class ClassWithJava8Date {
1131+
1132+
LocalDate date;
1133+
}
10641134
}

0 commit comments

Comments
 (0)