diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicUpdate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicUpdate.java
index 2b785ff52..00d148b89 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicUpdate.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicUpdate.java
@@ -19,6 +19,7 @@ import java.util.Arrays;
import java.util.Collections;
import org.bson.Document;
+import org.springframework.lang.Nullable;
/**
* @author Thomas Risberg
@@ -42,7 +43,7 @@ public class BasicUpdate extends Update {
}
@Override
- public Update set(String key, Object value) {
+ public Update set(String key, @Nullable Object value) {
updateObject.put("$set", Collections.singletonMap(key, value));
return this;
}
@@ -60,7 +61,7 @@ public class BasicUpdate extends Update {
}
@Override
- public Update push(String key, Object value) {
+ public Update push(String key, @Nullable Object value) {
updateObject.put("$push", Collections.singletonMap(key, value));
return this;
}
@@ -74,7 +75,7 @@ public class BasicUpdate extends Update {
}
@Override
- public Update addToSet(String key, Object value) {
+ public Update addToSet(String key, @Nullable Object value) {
updateObject.put("$addToSet", Collections.singletonMap(key, value));
return this;
}
@@ -86,7 +87,7 @@ public class BasicUpdate extends Update {
}
@Override
- public Update pull(String key, Object value) {
+ public Update pull(String key, @Nullable Object value) {
updateObject.put("$pull", Collections.singletonMap(key, value));
return this;
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java
index 4957bb5d5..edb79588d 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java
@@ -27,7 +27,6 @@ import java.util.Objects;
import java.util.Set;
import org.bson.Document;
-
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
@@ -68,7 +67,7 @@ public class Update implements UpdateDefinition {
* @param key
* @return
*/
- public static Update update(String key, Object value) {
+ public static Update update(String key, @Nullable Object value) {
return new Update().set(key, value);
}
@@ -110,11 +109,12 @@ public class Update implements UpdateDefinition {
* Update using the {@literal $set} update modifier
*
* @param key
- * @param value
- * @return
+ * @param value can be {@literal null}. In this case the property remains in the db with a {@literal null} value. To
+ * remove it use {@link #unset(String)}.
+ * @return this.
* @see MongoDB Update operator: $set
*/
- public Update set(String key, Object value) {
+ public Update set(String key, @Nullable Object value) {
addMultiFieldOperation("$set", key, value);
return this;
}
@@ -123,12 +123,12 @@ public class Update implements UpdateDefinition {
* Update using the {@literal $setOnInsert} update modifier
*
* @param key
- * @param value
+ * @param value can be {@literal null}.
* @return
* @see MongoDB Update operator:
* $setOnInsert
*/
- public Update setOnInsert(String key, Object value) {
+ public Update setOnInsert(String key, @Nullable Object value) {
addMultiFieldOperation("$setOnInsert", key, value);
return this;
}
@@ -175,7 +175,7 @@ public class Update implements UpdateDefinition {
* @return
* @see MongoDB Update operator: $push
*/
- public Update push(String key, Object value) {
+ public Update push(String key, @Nullable Object value) {
addMultiFieldOperation("$push", key, value);
return this;
}
@@ -238,7 +238,7 @@ public class Update implements UpdateDefinition {
* @see MongoDB Update operator:
* $addToSet
*/
- public Update addToSet(String key, Object value) {
+ public Update addToSet(String key, @Nullable Object value) {
addMultiFieldOperation("$addToSet", key, value);
return this;
}
@@ -264,7 +264,7 @@ public class Update implements UpdateDefinition {
* @return
* @see MongoDB Update operator: $pull
*/
- public Update pull(String key, Object value) {
+ public Update pull(String key, @Nullable Object value) {
addMultiFieldOperation("$pull", key, value);
return this;
}
@@ -472,7 +472,7 @@ public class Update implements UpdateDefinition {
this.keysToUpdate.add(key);
}
- protected void addMultiFieldOperation(String operator, String key, Object value) {
+ protected void addMultiFieldOperation(String operator, String key, @Nullable Object value) {
Assert.hasText(key, "Key/Path for update must not be null or blank.");
Object existingValue = this.modifierOps.get(operator);
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUpdateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUpdateTests.java
index 2f46f87d6..a90371de5 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUpdateTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUpdateTests.java
@@ -36,6 +36,7 @@ import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
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.test.util.EnableIfMongoServerVersion;
import org.springframework.data.mongodb.test.util.MongoServerCondition;
import org.springframework.data.mongodb.test.util.MongoTestUtils;
@@ -272,6 +273,22 @@ public class MongoTemplateUpdateTests {
}
+ @Test // DATAMMONGO-2423
+ void nullValueShouldBePropagatedToDatabase() {
+
+ Book currentRead = new Book();
+ currentRead.id = 1;
+ currentRead.author = new Author("Brent", "Weeks");
+ currentRead.title = "The Burning White";
+
+ template.save(currentRead);
+
+ template.update(Book.class).apply(new Update().set("title", null)).first();
+
+ assertThat(collection(Book.class).find(new org.bson.Document("_id", currentRead.id)).first()).containsEntry("title",
+ null);
+ }
+
private List all(Class> type) {
return collection(type).find(new org.bson.Document()).into(new ArrayList<>());
}