diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/AbstractMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/AbstractMongoConverter.java index 4dc9c500b..51fdb5e57 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/AbstractMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/AbstractMongoConverter.java @@ -29,8 +29,10 @@ import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.ConversionServiceFactory; import org.springframework.core.convert.support.GenericConversionService; import org.springframework.data.mongodb.core.convert.MongoConverters.BigIntegerToObjectIdConverter; +import org.springframework.data.mongodb.core.convert.MongoConverters.BigIntegerToStringConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.ObjectIdToBigIntegerConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.ObjectIdToStringConverter; +import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter; import org.springframework.data.mongodb.core.convert.MongoConverters.StringToObjectIdConverter; import com.mongodb.BasicDBList; @@ -87,6 +89,12 @@ public abstract class AbstractMongoConverter implements MongoConverter, Initiali if (!conversionService.canConvert(BigInteger.class, ObjectId.class)) { conversionService.addConverter(BigIntegerToObjectIdConverter.INSTANCE); } + if (!conversionService.canConvert(BigInteger.class, String.class)) { + conversionService.addConverter(BigIntegerToStringConverter.INSTANCE); + } + if (!conversionService.canConvert(String.class, BigInteger.class)) { + conversionService.addConverter(StringToBigIntegerConverter.INSTANCE); + } conversions.registerConvertersIn(conversionService); } 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 c350e0b74..a5e749a38 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 @@ -357,10 +357,10 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App final MongoPersistentProperty idProperty = entity.getIdProperty(); if (!dbo.containsField("_id") && null != idProperty) { Object idObj = null; - Class[] targetClasses = new Class[] { ObjectId.class, Object.class }; - for (Class targetClasse : targetClasses) { + Class[] targetClasses = new Class[] { ObjectId.class, String.class, Object.class }; + for (Class targetClass : targetClasses) { try { - idObj = wrapper.getProperty(idProperty, targetClasse, useFieldAccessOnly); + idObj = wrapper.getProperty(idProperty, targetClass, useFieldAccessOnly); if (null != idObj) { break; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java index 355410246..bd5608976 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java @@ -20,6 +20,7 @@ import java.math.BigInteger; import org.bson.types.ObjectId; import org.springframework.core.convert.converter.Converter; +import org.springframework.util.StringUtils; /** * Wrapper class to contain useful converters for the usage with Mongo. @@ -44,7 +45,7 @@ abstract class MongoConverters { INSTANCE; public String convert(ObjectId id) { - return id.toString(); + return id == null ? null : id.toString(); } } @@ -57,7 +58,7 @@ abstract class MongoConverters { INSTANCE; public ObjectId convert(String source) { - return new ObjectId(source); + return StringUtils.hasText(source) ? new ObjectId(source) : null; } } @@ -70,7 +71,7 @@ abstract class MongoConverters { INSTANCE; public BigInteger convert(ObjectId source) { - return new BigInteger(source.toString(), 16); + return source == null ? null : new BigInteger(source.toString(), 16); } } @@ -83,7 +84,7 @@ abstract class MongoConverters { INSTANCE; public ObjectId convert(BigInteger source) { - return new ObjectId(source.toString(16)); + return source == null ? null : new ObjectId(source.toString(16)); } } @@ -92,7 +93,7 @@ abstract class MongoConverters { INSTANCE; public String convert(BigDecimal source) { - return source.toString(); + return source == null ? null : source.toString(); } } @@ -100,7 +101,23 @@ abstract class MongoConverters { INSTANCE; public BigDecimal convert(String source) { - return new BigDecimal(source); + return StringUtils.hasText(source) ? new BigDecimal(source) : null; + } + } + + public static enum BigIntegerToStringConverter implements Converter { + INSTANCE; + + public String convert(BigInteger source) { + return source == null ? null : source.toString(); + } + } + + public static enum StringToBigIntegerConverter implements Converter { + INSTANCE; + + public BigInteger convert(String source) { + return StringUtils.hasText(source) ? new BigInteger(source) : null; } } } 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 1781f5e0d..d993fdf47 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 @@ -20,6 +20,7 @@ import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.math.BigDecimal; +import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -40,6 +41,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.core.convert.converter.Converter; +import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.convert.CustomConversions; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; @@ -508,6 +510,18 @@ public class MappingMongoConverterUnitTests { assertThat(((DBObject) map).keySet(), hasItem("en_US")); } + @Test + public void writesBigIntegerIdCorrectly() { + + ClassWithBigIntegerId foo = new ClassWithBigIntegerId(); + foo.id = BigInteger.valueOf(23L); + + DBObject result = new BasicDBObject(); + converter.write(foo, result); + + assertThat(result.get("_id"), is(instanceOf(String.class))); + } + class GenericType { T content; } @@ -571,6 +585,11 @@ public class MappingMongoConverterUnitTests { Locale locale; } + class ClassWithBigIntegerId { + @Id + BigInteger id; + } + private class LocalDateToDateConverter implements Converter { public Date convert(LocalDate source) {