Added handling of BigInteger.

Added converter to handle BigInteger values. Adapted id handling to try converting and object to String before taking the id as is. Made custom converter implementations safe against invocations with null.
This commit is contained in:
Oliver Gierke
2011-07-28 13:29:32 +02:00
parent fd7e41b753
commit a5328da460
4 changed files with 53 additions and 9 deletions

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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<BigInteger, String> {
INSTANCE;
public String convert(BigInteger source) {
return source == null ? null : source.toString();
}
}
public static enum StringToBigIntegerConverter implements Converter<String, BigInteger> {
INSTANCE;
public BigInteger convert(String source) {
return StringUtils.hasText(source) ? new BigInteger(source) : null;
}
}
}

View File

@@ -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> {
T content;
}
@@ -571,6 +585,11 @@ public class MappingMongoConverterUnitTests {
Locale locale;
}
class ClassWithBigIntegerId {
@Id
BigInteger id;
}
private class LocalDateToDateConverter implements Converter<LocalDate, Date> {
public Date convert(LocalDate source) {