diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index ca96626cc9..31a2cd72bb 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -18,6 +18,7 @@ 1.3 1.7.8 + 0.10.4 spring.data.mongodb ${basedir}/.. 1.01 @@ -224,6 +225,13 @@ test + + io.vavr + vavr + ${vavr} + test + + org.threeten threetenbp 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 54d0abc4b4..2e312f94d5 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 @@ -1295,7 +1295,8 @@ protected Object readCollectionOrArray(ConversionContext context, Collection */ @Deprecated protected Map readMap(TypeInformation type, Bson bson, ObjectPath path) { - return readMap(getConversionContext(path), bson, type); + //noinspection unchecked + return (Map) readMap(getConversionContext(path), bson, type); } /** @@ -1308,15 +1309,19 @@ protected Map readMap(TypeInformation type, Bson bson, Object * @return the converted {@link Map}, will never be {@literal null}. * @since 3.2 */ - protected Map readMap(ConversionContext context, Bson bson, TypeInformation targetType) { + protected Object readMap(ConversionContext context, Bson bson, TypeInformation targetType) { Assert.notNull(bson, "Document must not be null!"); Assert.notNull(targetType, "TypeInformation must not be null!"); - Class mapType = getTypeMapper().readType(bson, targetType).getType(); + TypeInformation typeInformation = getTypeMapper().readType(bson, targetType); + Class mapType = typeInformation.isSubTypeOf(Map.class) + ? targetType.getType() + : Map.class; TypeInformation keyType = targetType.getComponentType(); - TypeInformation valueType = targetType.getMapValueType() == null ? ClassTypeInformation.OBJECT + TypeInformation valueType = targetType.getMapValueType() == null + ? ClassTypeInformation.OBJECT : targetType.getRequiredMapValueType(); Class rawKeyType = keyType != null ? keyType.getType() : Object.class; @@ -1347,7 +1352,7 @@ protected Map readMap(ConversionContext context, Bson bson, Type }); - return map; + return getPotentiallyConvertedSimpleRead(map, targetType.getType()); } /* @@ -2032,27 +2037,7 @@ public S convert(Object source, TypeInformation Assert.notNull(source, "Source must not be null"); Assert.notNull(typeHint, "TypeInformation must not be null"); - if (conversions.hasCustomReadTarget(source.getClass(), typeHint.getType())) { - return (S) elementConverter.convert(source, typeHint); - } - - if (source instanceof Collection) { - - Class rawType = typeHint.getType(); - if (!Object.class.equals(rawType)) { - if (!rawType.isArray() && !ClassUtils.isAssignable(Iterable.class, rawType)) { - throw new MappingException( - String.format(INCOMPATIBLE_TYPES, source, source.getClass(), rawType, getPath())); - } - } - - if (typeHint.isCollectionLike() || typeHint.getType().isAssignableFrom(Collection.class)) { - return (S) collectionConverter.convert(this, (Collection) source, typeHint); - } - } - if (typeHint.isMap()) { - if (ClassUtils.isAssignable(Document.class, typeHint.getType())) { return (S) documentConverter.convert(this, BsonUtils.asBson(source), typeHint); } @@ -2065,6 +2050,14 @@ public S convert(Object source, TypeInformation String.format("Expected map like structure but found %s", source.getClass())); } + if (source instanceof Collection) { + return (S) collectionConverter.convert(this, (Collection) source, typeHint); + } + + if (conversions.hasCustomReadTarget(source.getClass(), typeHint.getType())) { + return (S) elementConverter.convert(source, typeHint); + } + if (source instanceof DBRef) { return (S) dbRefConverter.convert(this, (DBRef) source, typeHint); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomListReadingConvertersUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomListReadingConvertersUnitTests.java new file mode 100644 index 0000000000..db24027973 --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomListReadingConvertersUnitTests.java @@ -0,0 +1,147 @@ +/* + * Copyright 2011-2021 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.mongodb.core.convert; + +import org.bson.Document; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.core.convert.ConversionFailedException; +import org.springframework.core.convert.converter.Converter; +import org.springframework.data.convert.CustomConversions; +import org.springframework.data.convert.ReadingConverter; +import org.springframework.data.mongodb.core.mapping.MongoMappingContext; + +import java.util.Arrays; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.verify; + +/** + * Test case to verify correct usage of custom {@link Converter} implementations for different List implementations to be used. + * + * @author Jürgen Diez + */ +@ExtendWith(MockitoExtension.class) +class CustomListReadingConvertersUnitTests { + + private MappingMongoConverter converter; + + @Mock JavaListReadingConverter javaListReadingConverter; + @Mock IterableListReadingConverter iterableListReadingConverter; + @Mock CustomListReadingConverter customListReadingConverter; + @Captor ArgumentCaptor> enumListCaptor; + + private Document document; + + @BeforeEach + void setUp() { + CustomConversions conversions = new MongoCustomConversions( + Arrays.asList(javaListReadingConverter, iterableListReadingConverter, customListReadingConverter)); + + MongoMappingContext context = new MongoMappingContext(); + context.setSimpleTypeHolder(conversions.getSimpleTypeHolder()); + context.initialize(); + + converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, context); + converter.setCustomConversions(conversions); + converter.afterPropertiesSet(); + + document = new Document(); + document.append("list", Arrays.asList("ENUM_VALUE1", "ENUM_VALUE2")); + } + + @Test + void invokeJavaListConverterForEnumsAfterResolvingTheListTypes() { + + converter.read(TestJavaList.class, document); + + verify(javaListReadingConverter).convert(enumListCaptor.capture()); + assertThat(enumListCaptor.getValue()).containsExactly(TestEnum.ENUM_VALUE1, TestEnum.ENUM_VALUE2); + } + + @Test + void invokeExtendedIterableListConverterForEnumsAfterResolvingTheListTypes() { + + converter.read(TestIterableList.class, document); + + verify(iterableListReadingConverter).convert(enumListCaptor.capture()); + assertThat(enumListCaptor.getValue()).containsExactly(TestEnum.ENUM_VALUE1, TestEnum.ENUM_VALUE2); + } + + @Test + void invokeOtherListConverterForEnumsAfterResolvingTheListTypes() { + + converter.read(TestOtherList.class, document); + + verify(customListReadingConverter).convert(enumListCaptor.capture()); + assertThat(enumListCaptor.getValue()).containsExactly(TestEnum.ENUM_VALUE1, TestEnum.ENUM_VALUE2); + } + + @Test + void throwExceptionIfNoConverterIsGivenForACustomListImplementation() { + + assertThrows(ConversionFailedException.class, () -> converter.read(TestNoConverterList.class, document)); + } + + + @ReadingConverter + private interface JavaListReadingConverter extends Converter, List> {} + + @ReadingConverter + private interface IterableListReadingConverter extends Converter, Iterable> {} + + @ReadingConverter + private interface CustomListReadingConverter extends Converter, OtherList> {} + + private enum TestEnum { + ENUM_VALUE1, + ENUM_VALUE2 + } + + private static class TestJavaList { + @SuppressWarnings("unused") + List list; + } + + private static class TestIterableList { + @SuppressWarnings("unused") + Iterable list; + } + + private static class TestOtherList { + @SuppressWarnings("unused") + OtherList list; + } + + private interface OtherList { + } + + private static class TestNoConverterList { + @SuppressWarnings("unused") + NoConverterList list; + } + + private interface NoConverterList { + } + +} diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomMapReadingConvertersUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomMapReadingConvertersUnitTests.java new file mode 100644 index 0000000000..12b286a0ed --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/CustomMapReadingConvertersUnitTests.java @@ -0,0 +1,205 @@ +/* + * Copyright 2011-2021 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.mongodb.core.convert; + +import org.bson.Document; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.core.convert.ConversionException; +import org.springframework.core.convert.converter.Converter; +import org.springframework.data.convert.CustomConversions; +import org.springframework.data.convert.ReadingConverter; +import org.springframework.data.mongodb.core.mapping.MongoMappingContext; + +import java.util.*; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.data.MapEntry.entry; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.verify; + +/** + * Test case to verify correct usage of custom {@link Converter} implementations for different Map implementations to be used. + * + * @author Jürgen Diez + */ +@ExtendWith(MockitoExtension.class) +class CustomMapReadingConvertersUnitTests { + + private MappingMongoConverter converter; + + @Mock JavaMapReadingConverter javaMapReadingConverter; + @Mock ExtendedMapReadingConverter extendedMapReadingConverter; + @Mock VavrMapReadingConverter vavrMapReadingConverter; + @Captor ArgumentCaptor> enumMapCaptor; + + private Document source; + + @BeforeEach + void setUp() { + CustomConversions conversions = new MongoCustomConversions( + Arrays.asList(javaMapReadingConverter, extendedMapReadingConverter, vavrMapReadingConverter)); + + MongoMappingContext context = new MongoMappingContext(); + context.setSimpleTypeHolder(conversions.getSimpleTypeHolder()); + context.initialize(); + + converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, context); + converter.setCustomConversions(conversions); + converter.afterPropertiesSet(); + + source = new Document(); + Document map = new Document(); + map.append("key1", "ENUM_VALUE1"); + map.append("key2", "ENUM_VALUE2"); + source.append("map", map); + } + + @Test + void invokeJavaMapConverterForEnumsAfterResolvingTheMapTypes() { + + converter.read(TestJavaMap.class, source); + + verify(javaMapReadingConverter).convert(enumMapCaptor.capture()); + assertThat(enumMapCaptor.getValue()).containsOnly(entry("key1", TestEnum.ENUM_VALUE1), entry("key2", TestEnum.ENUM_VALUE2)); + } + + @Test + void invokeExtendedMapConverterForEnumsAfterResolvingTheMapTypes() { + + converter.read(TestExtendedMap.class, source); + + verify(extendedMapReadingConverter).convert(enumMapCaptor.capture()); + assertThat(enumMapCaptor.getValue()).containsOnly(entry("key1", TestEnum.ENUM_VALUE1), entry("key2", TestEnum.ENUM_VALUE2)); + } + + @Test + void invokeVavrMapConverterForEnumsAfterResolvingTheMapTypes() { + + converter.read(TestVavrMap.class, source); + + verify(vavrMapReadingConverter).convert(enumMapCaptor.capture()); + assertThat(enumMapCaptor.getValue()).containsOnly(entry("key1", TestEnum.ENUM_VALUE1), entry("key2", TestEnum.ENUM_VALUE2)); + } + + + @ReadingConverter + private interface JavaMapReadingConverter extends Converter, Map> { + } + + @ReadingConverter + private interface ExtendedMapReadingConverter extends Converter, ExtendedMap> { + } + + @ReadingConverter + private interface VavrMapReadingConverter extends Converter, io.vavr.collection.Map> { + } + + private enum TestEnum { + ENUM_VALUE1, + ENUM_VALUE2 + } + + private static class TestJavaMap { + @SuppressWarnings("unused") + Map map; + } + + private static class TestExtendedMap { + @SuppressWarnings("unused") + ExtendedMap map; + } + + private static class TestVavrMap { + @SuppressWarnings("unused") + io.vavr.collection.Map map; + } + + private static class ExtendedMap implements Map { + HashMap internalMap = new HashMap<>(); + + @Override + public int size() { + return internalMap.size(); + } + + @Override + public boolean isEmpty() { + return internalMap.isEmpty(); + } + + @Override + public boolean containsKey(Object o) { + return internalMap.containsKey(o); + } + + @Override + public boolean containsValue(Object o) { + return internalMap.containsValue(o); + } + + @Override + public V get(Object o) { + return internalMap.get(o); + } + + @Nullable + @Override + public V put(K k, V v) { + return internalMap.put(k, v); + } + + @Override + public V remove(Object o) { + return internalMap.remove(o); + } + + @Override + public void putAll(@NotNull Map map) { + internalMap.putAll(map); + } + + @Override + public void clear() { + internalMap.clear(); + } + + @NotNull + @Override + public Set keySet() { + return internalMap.keySet(); + } + + @NotNull + @Override + public Collection values() { + return internalMap.values(); + } + + @NotNull + @Override + public Set> entrySet() { + return internalMap.entrySet(); + } + } +} \ No newline at end of file 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 d4c735fd23..ff80cc3bef 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 @@ -15,21 +15,12 @@ */ package org.springframework.data.mongodb.core.convert; -import static java.time.ZoneId.*; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; -import static org.springframework.data.mongodb.core.DocumentTestUtils.*; - +import com.mongodb.BasicDBList; +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; +import com.mongodb.DBRef; import lombok.EqualsAndHashCode; import lombok.RequiredArgsConstructor; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.net.URL; -import java.time.LocalDateTime; -import java.time.temporal.ChronoUnit; -import java.util.*; - import org.bson.types.Binary; import org.bson.types.Code; import org.bson.types.Decimal128; @@ -42,12 +33,12 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; - import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.ConversionNotSupportedException; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationContext; import org.springframework.context.support.StaticApplicationContext; +import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.converter.Converter; import org.springframework.data.annotation.Id; @@ -57,13 +48,7 @@ import org.springframework.data.convert.CustomConversions; import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.WritingConverter; -import org.springframework.data.geo.Box; -import org.springframework.data.geo.Circle; -import org.springframework.data.geo.Distance; -import org.springframework.data.geo.Metrics; -import org.springframework.data.geo.Point; -import org.springframework.data.geo.Polygon; -import org.springframework.data.geo.Shape; +import org.springframework.data.geo.*; import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.callback.EntityCallbacks; import org.springframework.data.mapping.model.MappingInstantiationException; @@ -72,24 +57,23 @@ import org.springframework.data.mongodb.core.convert.DocumentAccessorUnitTests.ProjectingType; import org.springframework.data.mongodb.core.convert.MappingMongoConverterUnitTests.ClassWithMapUsingEnumAsKey.FooBarEnum; import org.springframework.data.mongodb.core.geo.Sphere; -import org.springframework.data.mongodb.core.mapping.Document; -import org.springframework.data.mongodb.core.mapping.Field; -import org.springframework.data.mongodb.core.mapping.FieldType; -import org.springframework.data.mongodb.core.mapping.MongoMappingContext; -import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; -import org.springframework.data.mongodb.core.mapping.PersonPojoStringId; -import org.springframework.data.mongodb.core.mapping.TextScore; -import org.springframework.data.mongodb.core.mapping.Unwrapped; +import org.springframework.data.mongodb.core.mapping.*; import org.springframework.data.mongodb.core.mapping.event.AfterConvertCallback; import org.springframework.data.util.ClassTypeInformation; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; import org.springframework.test.util.ReflectionTestUtils; -import com.mongodb.BasicDBList; -import com.mongodb.BasicDBObject; -import com.mongodb.DBObject; -import com.mongodb.DBRef; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.URL; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.*; + +import static java.time.ZoneId.systemDefault; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; +import static org.springframework.data.mongodb.core.DocumentTestUtils.assertTypeHint; +import static org.springframework.data.mongodb.core.DocumentTestUtils.getAsDocument; /** * Unit tests for {@link MappingMongoConverter}. @@ -1614,7 +1598,7 @@ void rejectsBasicDbListToBeConvertedIntoComplexType() { org.bson.Document source = new org.bson.Document("attributes", outer); - assertThatExceptionOfType(MappingException.class).isThrownBy(() -> converter.read(Item.class, source)); + assertThatExceptionOfType(ConversionFailedException.class).isThrownBy(() -> converter.read(Item.class, source)); } @Test // DATAMONGO-1058 @@ -2170,6 +2154,7 @@ void resolveDBRefMapValueShouldInvokeCallbacks() { verify(afterConvertCallback).onAfterConvert(eq(result.personMap.get("foo")), eq(new org.bson.Document()), any()); } + @SuppressWarnings("unchecked") @Test // DATAMONGO-2300 void readAndConvertDBRefNestedByMapCorrectly() { @@ -2182,7 +2167,7 @@ void readAndConvertDBRefNestedByMapCorrectly() { MappingMongoConverter spyConverter = spy(converter); Mockito.doReturn(cluster).when(spyConverter).readRef(dbRef); - Map result = spyConverter.readMap(spyConverter.getConversionContext(ObjectPath.ROOT), data, + Map result = (Map) spyConverter.readMap(spyConverter.getConversionContext(ObjectPath.ROOT), data, ClassTypeInformation.MAP); assertThat(((Map) result.get("cluster")).get("_id")).isEqualTo(100L); @@ -2434,95 +2419,6 @@ void shouldUseMostConcreteCustomConversionTargetOnRead() { } - @Test // GH-3660 - void usesCustomConverterForMapTypesOnWrite() { - - converter = new MappingMongoConverter(resolver, mappingContext); - converter.setCustomConversions(MongoCustomConversions.create(it -> { - it.registerConverter(new TypeImplementingMapToDocumentConverter()); - })); - converter.afterPropertiesSet(); - - TypeImplementingMap source = new TypeImplementingMap("one", 2); - org.bson.Document target = new org.bson.Document(); - - converter.write(source, target); - - assertThat(target).containsEntry("1st", "one").containsEntry("2nd", 2); - } - - @Test // GH-3660 - void usesCustomConverterForTypesImplementingMapOnWrite() { - - converter = new MappingMongoConverter(resolver, mappingContext); - converter.setCustomConversions(MongoCustomConversions.create(it -> { - it.registerConverter(new TypeImplementingMapToDocumentConverter()); - })); - converter.afterPropertiesSet(); - - TypeImplementingMap source = new TypeImplementingMap("one", 2); - org.bson.Document target = new org.bson.Document(); - - converter.write(source, target); - - assertThat(target).containsEntry("1st", "one").containsEntry("2nd", 2); - } - - @Test // GH-3660 - void usesCustomConverterForTypesImplementingMapOnRead() { - - converter = new MappingMongoConverter(resolver, mappingContext); - converter.setCustomConversions(MongoCustomConversions.create(it -> { - it.registerConverter(new DocumentToTypeImplementingMapConverter()); - })); - converter.afterPropertiesSet(); - - org.bson.Document source = new org.bson.Document("1st", "one") - .append("2nd", 2) - .append("_class", TypeImplementingMap.class.getName()); - - TypeImplementingMap target = converter.read(TypeImplementingMap.class, source); - - assertThat(target).isEqualTo(new TypeImplementingMap("one", 2)); - } - - @Test // GH-3660 - void usesCustomConverterForPropertiesUsingTypesThatImplementMapOnWrite() { - - converter = new MappingMongoConverter(resolver, mappingContext); - converter.setCustomConversions(MongoCustomConversions.create(it -> { - it.registerConverter(new TypeImplementingMapToDocumentConverter()); - })); - converter.afterPropertiesSet(); - - TypeWrappingTypeImplementingMap source = new TypeWrappingTypeImplementingMap(); - source.typeImplementingMap = new TypeImplementingMap("one", 2); - org.bson.Document target = new org.bson.Document(); - - converter.write(source, target); - - assertThat(target).containsEntry("typeImplementingMap", new org.bson.Document("1st", "one").append("2nd", 2)); - } - - @Test // GH-3660 - void usesCustomConverterForPropertiesUsingTypesImplementingMapOnRead() { - - converter = new MappingMongoConverter(resolver, mappingContext); - converter.setCustomConversions(MongoCustomConversions.create(it -> { - it.registerConverter(new DocumentToTypeImplementingMapConverter()); - })); - converter.afterPropertiesSet(); - - org.bson.Document source = new org.bson.Document("typeImplementingMap", - new org.bson.Document("1st", "one") - .append("2nd", 2)) - .append("_class", TypeWrappingTypeImplementingMap.class.getName()); - - TypeWrappingTypeImplementingMap target = converter.read(TypeWrappingTypeImplementingMap.class, source); - - assertThat(target.typeImplementingMap).isEqualTo(new TypeImplementingMap("one", 2)); - } - @Test // GH-3407 void shouldWriteNullPropertyCorrectly() { @@ -3184,26 +3080,6 @@ public SubTypeOfGenericType convert(org.bson.Document source) { } } - @WritingConverter - static class TypeImplementingMapToDocumentConverter implements Converter { - - @Nullable - @Override - public org.bson.Document convert(TypeImplementingMap source) { - return new org.bson.Document("1st", source.val1).append("2nd", source.val2); - } - } - - @ReadingConverter - static class DocumentToTypeImplementingMapConverter implements Converter { - - @Nullable - @Override - public TypeImplementingMap convert(org.bson.Document source) { - return new TypeImplementingMap(source.getString("1st"), source.getInteger("2nd")); - } - } - @ReadingConverter public static class MongoSimpleTypeConverter implements Converter { @@ -3213,88 +3089,6 @@ public byte[] convert(Binary source) { } } - static class TypeWrappingTypeImplementingMap { - - String id; - TypeImplementingMap typeImplementingMap; - } - - @EqualsAndHashCode - static class TypeImplementingMap implements Map { - - String val1; - int val2; - - TypeImplementingMap(String val1, int val2) { - this.val1 = val1; - this.val2 = val2; - } - - @Override - public int size() { - return 0; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean containsKey(Object key) { - return false; - } - - @Override - public boolean containsValue(Object value) { - return false; - } - - @Override - public String get(Object key) { - return null; - } - - @Nullable - @Override - public String put(String key, String value) { - return null; - } - - @Override - public String remove(Object key) { - return null; - } - - @Override - public void putAll(@NonNull Map m) { - - } - - @Override - public void clear() { - - } - - @NonNull - @Override - public Set keySet() { - return null; - } - - @NonNull - @Override - public Collection values() { - return null; - } - - @NonNull - @Override - public Set> entrySet() { - return null; - } - } - static class WithRawDocumentProperties { String id;