From 08c5e5a8106dbdc2994ec40cc939796bb4d42ce8 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Mon, 12 Jul 2021 07:56:59 +0200 Subject: [PATCH] Fix raw document conversion in Collection like properties. Along the lines make sure to convert map like structures correctly if they do not come as a Document, eg. cause they got converted to a plain Map in a post load, pre convert event. Closes #3702 Original pull request: #3704. --- .../core/convert/MappingMongoConverter.java | 14 ++++++- .../MappingMongoConverterUnitTests.java | 39 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java index 601555ca0..0f707888d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java @@ -1907,7 +1907,19 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } if (typeHint.isMap()) { - return (S) mapConverter.convert(this, (Bson) source, typeHint); + + if(ClassUtils.isAssignable(Document.class, typeHint.getType())) { + return (S) documentConverter.convert(this, (Bson) source, typeHint); + } + + if(source instanceof Bson) { + return (S) mapConverter.convert(this, (Bson) source, typeHint); + } + if(source instanceof Map) { + return (S) mapConverter.convert(this, new Document((Map) source), typeHint); + } + + throw new IllegalArgumentException(String.format("Expected map like structure but found %s", source.getClass())); } if (source instanceof DBRef) { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java index 911c0a2bc..a7532b93a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java @@ -2571,6 +2571,38 @@ class MappingMongoConverterUnitTests { assertThat(target.content).isInstanceOf(byte[].class); } + @Test // GH-3702 + void readsRawDocument() { + + org.bson.Document source = new org.bson.Document("_id", "id-1").append("raw", new org.bson.Document("simple", 1).append("document", new org.bson.Document("inner-doc", 1))); + + WithRawDocumentProperties target = converter.read(WithRawDocumentProperties.class, source); + + assertThat(target.raw).isInstanceOf(org.bson.Document.class).isEqualTo( new org.bson.Document("simple", 1).append("document", new org.bson.Document("inner-doc", 1))); + } + + @Test // GH-3702 + void readsListOfRawDocument() { + + org.bson.Document source = new org.bson.Document("_id", "id-1").append("listOfRaw", Arrays.asList(new org.bson.Document("simple", 1).append("document", new org.bson.Document("inner-doc", 1)))); + + WithRawDocumentProperties target = converter.read(WithRawDocumentProperties.class, source); + + assertThat(target.listOfRaw) + .containsExactly(new org.bson.Document("simple", 1).append("document", new org.bson.Document("inner-doc", 1))); + } + + @Test // GH-3692 + void readsMapThatDoesNotComeAsDocument() { + + org.bson.Document source = new org.bson.Document("_id", "id-1").append("mapOfObjects", Collections.singletonMap("simple", 1)); + + ClassWithMapProperty target = converter.read(ClassWithMapProperty.class, source); + + assertThat(target.mapOfObjects).containsEntry("simple",1); + + } + static class GenericType { T content; } @@ -3229,4 +3261,11 @@ class MappingMongoConverterUnitTests { return null; } } + + static class WithRawDocumentProperties { + + String id; + org.bson.Document raw; + List listOfRaw; + } }