Browse Source

DATAMONGO-807 - findAndModify(…) now retains type information.

Using findAndUpdate(…) did not retain type information when used to update a whole nested type instead of single fields within the type. We now use the UpdateMapper instead of QueryMapper in doFindAndModify(…).

Original pull request: #110.
pull/125/merge
Christoph Strobl 12 years ago committed by Oliver Gierke
parent
commit
de0c4109d7
  1. 2
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java
  2. 35
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java
  3. 68
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java

2
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java

@ -1561,8 +1561,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass); MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
DBObject mappedUpdate = queryMapper.getMappedObject(update.getUpdateObject(), entity);
DBObject mappedQuery = queryMapper.getMappedObject(query, entity); DBObject mappedQuery = queryMapper.getMappedObject(query, entity);
DBObject mappedUpdate = updateMapper.getMappedObject(update.getUpdateObject(), entity);
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("findAndModify using query: " + mappedQuery + " fields: " + fields + " sort: " + sort LOGGER.debug("findAndModify using query: " + mappedQuery + " fields: " + fields + " sort: " + sort

35
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java

@ -1800,12 +1800,12 @@ public class MongoTemplateTests {
Document doc = new Document(); Document doc = new Document();
doc.id = "4711"; doc.id = "4711";
doc.model = new ModelA().withValue("foo"); doc.model = new ModelA("foo");
template.insert(doc); template.insert(doc);
Query query = new Query(Criteria.where("id").is(doc.id)); Query query = new Query(Criteria.where("id").is(doc.id));
String newModelValue = "bar"; String newModelValue = "bar";
Update update = Update.update("model", new ModelA().withValue(newModelValue)); Update update = Update.update("model", new ModelA(newModelValue));
template.updateFirst(query, update, Document.class); template.updateFirst(query, update, Document.class);
Document result = template.findOne(query, Document.class); Document result = template.findOne(query, Document.class);
@ -2182,26 +2182,43 @@ public class MongoTemplateTests {
assertThat(template.find(query, Sample.class), is(not(empty()))); assertThat(template.find(query, Sample.class), is(not(empty())));
} }
/**
* @see DATAMONGO-807
*/
@Test
public void findAndModifyShouldRetrainTypeInformationWithinUpdatedType() {
Document document = new Document();
document.model = new ModelA("value1");
template.save(document);
Query query = query(where("id").is(document.id));
Update update = Update.update("model", new ModelA("value2"));
template.findAndModify(query, update, Document.class);
Document retrieved = template.findOne(query, Document.class);
Assert.assertThat(retrieved.model, instanceOf(ModelA.class));
Assert.assertThat(retrieved.model.value(), equalTo("value2"));
}
static interface Model { static interface Model {
String value(); String value();
Model withValue(String value);
} }
static class ModelA implements Model { static class ModelA implements Model {
private String value; private String value;
ModelA(String value) {
this.value = value;
}
@Override @Override
public String value() { public String value() {
return this.value; return this.value;
} }
@Override
public Model withValue(String value) {
this.value = value;
return this;
}
} }
static class Document { static class Document {

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

@ -1,5 +1,5 @@
/* /*
* Copyright 2013 the original author or authors. * Copyright 2013-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,6 +36,7 @@ import com.mongodb.DBObject;
* Unit tests for {@link UpdateMapper}. * Unit tests for {@link UpdateMapper}.
* *
* @author Oliver Gierke * @author Oliver Gierke
* @author Christoph Strobl
*/ */
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class UpdateMapperUnitTests { public class UpdateMapperUnitTests {
@ -68,6 +69,71 @@ public class UpdateMapperUnitTests {
assertThat(list.get("_class"), is((Object) ConcreteChildClass.class.getName())); assertThat(list.get("_class"), is((Object) ConcreteChildClass.class.getName()));
} }
/**
* @see DATAMONGO-807
*/
@Test
public void updateMapperShouldRetainTypeInformationForNestedEntities() {
Update update = Update.update("model", new ModelImpl(1));
UpdateMapper mapper = new UpdateMapper(converter);
DBObject mappedObject = mapper.getMappedObject(update.getUpdateObject(),
context.getPersistentEntity(ModelWrapper.class));
DBObject set = DBObjectUtils.getAsDBObject(mappedObject, "$set");
DBObject modelDbObject = (DBObject) set.get("model");
assertThat(modelDbObject.get("_class"), not(nullValue()));
}
/**
* @see DATAMONGO-807
*/
@Test
public void updateMapperShouldNotPersistTypeInformationForKnownSimpleTypes() {
Update update = Update.update("model.value", 1);
UpdateMapper mapper = new UpdateMapper(converter);
DBObject mappedObject = mapper.getMappedObject(update.getUpdateObject(),
context.getPersistentEntity(ModelWrapper.class));
DBObject set = DBObjectUtils.getAsDBObject(mappedObject, "$set");
assertThat(set.get("_class"), nullValue());
}
/**
* @see DATAMONGO-807
*/
@Test
public void updateMapperShouldNotPersistTypeInformationForNullValues() {
Update update = Update.update("model", null);
UpdateMapper mapper = new UpdateMapper(converter);
DBObject mappedObject = mapper.getMappedObject(update.getUpdateObject(),
context.getPersistentEntity(ModelWrapper.class));
DBObject set = DBObjectUtils.getAsDBObject(mappedObject, "$set");
assertThat(set.get("_class"), nullValue());
}
static interface Model {
}
static class ModelImpl implements Model {
public int value;
public ModelImpl(int value) {
this.value = value;
}
}
public class ModelWrapper {
Model model;
}
static class ParentClass { static class ParentClass {
String id; String id;

Loading…
Cancel
Save