DATAMONGO-571 - Fixed setting null values during update of versioned entities.

In case of updating a versioned object,the Update object is now constructed from plain key value pairs, not using $set anymore. This will correctly set the null values in the updated document.
This commit is contained in:
Oliver Gierke
2013-04-11 12:01:38 +02:00
parent 5c47f1ae9e
commit d645c778c3
2 changed files with 51 additions and 4 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2012 the original author or authors.
* Copyright 2010-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -52,7 +52,10 @@ public class Update {
/**
* Creates an {@link Update} instance from the given {@link DBObject}. Allows to explicitly exlude fields from making
* it into the created {@link Update} object.
* it into the created {@link Update} object. Note, that this will set attributes directly and <em>not</em> use
* {@literal $set}. This means fields not given in the {@link DBObject} will be nulled when executing the update. To
* create an only-updating {@link Update} instance of a {@link DBObject}, call {@link #set(String, Object)} for each
* value in it.
*
* @param object the source {@link DBObject} to create the update from.
* @param exclude the fields to exclude.
@@ -69,7 +72,7 @@ public class Update {
continue;
}
update.set(key, object.get(key));
update.modifierOps.put(key, object.get(key));
}
return update;
@@ -160,7 +163,7 @@ public class Update {
* @return
*/
public Update pop(String key, Position pos) {
addMultiFieldOperation("$pop", key, (pos == Position.FIRST ? -1 : 1));
addMultiFieldOperation("$pop", key, pos == Position.FIRST ? -1 : 1);
return this;
}

View File

@@ -47,6 +47,7 @@ import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.annotation.Version;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
import org.springframework.data.mongodb.MongoDbFactory;
@@ -1533,6 +1534,42 @@ public class MongoTemplateTests {
assertThat(template.count(query, collectionName), is(1L));
}
/**
* @see DATAMONGO-571
*/
@Test
public void nullsPropertiesForVersionObjectUpdates() {
VersionedPerson person = new VersionedPerson();
person.firstname = "Dave";
person.lastname = "Matthews";
template.save(person);
assertThat(person.id, is(notNullValue()));
person.lastname = null;
template.save(person);
person = template.findOne(query(where("id").is(person.id)), VersionedPerson.class);
assertThat(person.lastname, is(nullValue()));
}
/**
* @see DATAMONGO-571
*/
@Test
public void nullsValuesForUpdatesOfUnversionedEntity() {
Person person = new Person("Dave");
template.save(person);
person.setFirstName(null);
template.save(person);
person = template.findOne(query(where("id").is(person.getId())), Person.class);
assertThat(person.getFirstName(), is(nullValue()));
}
static class MyId {
String first;
@@ -1602,4 +1639,11 @@ public class MongoTemplateTests {
String state;
String city;
}
static class VersionedPerson {
@Version
Long version;
String id, firstname, lastname;
}
}