DATAMONGO-2028 - Reinstantiate Map-like document conversion on save.

We now convert values of Map-like documents (Document, DBObject, Map) before writing these into MongoDB. Conversion got lost as result of a refactoring and missing tests.
This commit is contained in:
Mark Paluch
2018-07-17 09:41:59 +02:00
parent 088928c64a
commit 9d1471bb28
2 changed files with 47 additions and 5 deletions

View File

@@ -47,6 +47,7 @@ import com.mongodb.util.JSONParseException;
* Common operations performed on an entity in the context of it's mapping metadata.
*
* @author Oliver Gierke
* @author Mark Paluch
* @since 2.1
* @see MongoTemplate
* @see ReactiveMongoTemplate
@@ -70,11 +71,11 @@ class EntityOperations {
Assert.notNull(entity, "Bean must not be null!");
if (entity instanceof String) {
return new SimpleEntity(parse(entity.toString()));
return new UnmappedEntity(parse(entity.toString()));
}
if (entity instanceof Map) {
return new SimpleEntity((Map<String, Object>) entity);
return new SimpleMappedEntity((Map<String, Object>) entity);
}
return MappedEntity.of(entity, context);
@@ -94,11 +95,11 @@ class EntityOperations {
Assert.notNull(conversionService, "ConversionService must not be null!");
if (entity instanceof String) {
return new SimpleEntity(parse(entity.toString()));
return new UnmappedEntity(parse(entity.toString()));
}
if (entity instanceof Map) {
return new SimpleEntity((Map<String, Object>) entity);
return new SimpleMappedEntity((Map<String, Object>) entity);
}
return AdaptibleMappedEntity.of(entity, context, conversionService);
@@ -286,7 +287,7 @@ class EntityOperations {
}
@RequiredArgsConstructor
private static class SimpleEntity<T extends Map<String, Object>> implements AdaptibleEntity<T> {
private static class UnmappedEntity<T extends Map<String, Object>> implements AdaptibleEntity<T> {
private final T map;
@@ -388,6 +389,31 @@ class EntityOperations {
}
}
private static class SimpleMappedEntity<T extends Map<String, Object>> extends UnmappedEntity<T> {
public SimpleMappedEntity(T map) {
super(map);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.EntityOperations.PersistableSource#toMappedDocument(org.springframework.data.mongodb.core.convert.MongoWriter)
*/
@Override
@SuppressWarnings("unchecked")
public MappedDocument toMappedDocument(MongoWriter<? super T> writer) {
T bean = getBean();
bean = (T) (bean instanceof Document //
? (Document) bean //
: new Document(bean));
Document document = new Document();
writer.write(bean, document);
return MappedDocument.of(document);
}
}
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
private static class MappedEntity<T> implements Entity<T> {

View File

@@ -26,6 +26,8 @@ import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.query.Query.*;
import static org.springframework.data.mongodb.core.query.Update.*;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -36,11 +38,13 @@ import lombok.experimental.Wither;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.Duration;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.hamcrest.collection.IsMapContaining;
import org.joda.time.DateTime;
@@ -2061,6 +2065,18 @@ public class MongoTemplateTests {
assertThat(result.get(0).field, is(value));
}
@Test // DATAMONGO-2028
public void allowInsertOfDbObjectWithMappedTypes() {
DBObject dbObject = new BasicDBObject("_id", "foo").append("duration", Duration.ofSeconds(100));
template.insert(dbObject, "sample");
List<org.bson.Document> result = template.findAll(org.bson.Document.class, "sample");
assertThat(result.size(), is(1));
assertThat(result.get(0).getString("_id"), is("foo"));
assertThat(result.get(0).getString("duration"), is("PT1M40S"));
}
@Test // DATAMONGO-816
public void shouldExecuteQueryShouldMapQueryBeforeQueryExecution() {