From febe7039548558def9c472da0f6527734b00a4e8 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Tue, 26 Aug 2014 19:56:42 +0200 Subject: [PATCH] DATAMONGO-1034 - Explicitly reject incompatible types in MappingMongoConverter. Improved the exception message that is occurs if the source document contains a BasicDBList but has to be converted into a complex object. We now explicitly hint to use a custom Converter to manually. --- .../core/convert/MappingMongoConverter.java | 6 +++++ .../MappingMongoConverterUnitTests.java | 27 +++++++++++++++++++ 2 files changed, 33 insertions(+) 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 527acc68e..87d9efa50 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 @@ -76,6 +76,8 @@ import com.mongodb.DBRef; */ public class MappingMongoConverter extends AbstractMongoConverter implements ApplicationContextAware { + private static final String INCOMPATIBLE_TYPES = "Cannot convert %1$s of type %2$s into an instance of %3$s! Implement a custom Converter<%2$s, %3$s> and register it with the CustomConversions. Parent object was: %4$s"; + protected static final Logger LOGGER = LoggerFactory.getLogger(MappingMongoConverter.class); protected final MappingContext, MongoPersistentProperty> mappingContext; @@ -214,6 +216,10 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App return (S) readMap(typeToUse, dbo, parent); } + if (dbo instanceof BasicDBList) { + throw new MappingException(String.format(INCOMPATIBLE_TYPES, dbo, BasicDBList.class, typeToUse.getType(), parent)); + } + // Retrieve persistent entity info MongoPersistentEntity persistentEntity = (MongoPersistentEntity) mappingContext .getPersistentEntity(typeToUse); 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 b703b92ec..dff4ce39b 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 @@ -45,7 +45,9 @@ import org.hamcrest.Matchers; import org.joda.time.LocalDate; import org.junit.Before; import org.junit.Ignore; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; @@ -99,6 +101,8 @@ public class MappingMongoConverterUnitTests { @Mock ApplicationContext context; @Mock DbRefResolver resolver; + public @Rule ExpectedException exception = ExpectedException.none(); + @Before public void setUp() { @@ -1839,6 +1843,29 @@ public class MappingMongoConverterUnitTests { verify(mock, times(1)).initialize(); } + /** + * @see DATAMONGO-1034 + */ + @Test + public void rejectsBasicDbListToBeConvertedIntoComplexType() { + + BasicDBList inner = new BasicDBList(); + inner.add("key"); + inner.add("value"); + + BasicDBList outer = new BasicDBList(); + outer.add(inner); + outer.add(inner); + + BasicDBObject source = new BasicDBObject("attributes", outer); + + exception.expect(MappingException.class); + exception.expectMessage(Item.class.getName()); + exception.expectMessage(BasicDBList.class.getName()); + + converter.read(Item.class, source); + } + static class GenericType { T content; }