DATAMONGO-2328 - Add missing target type conversions for field level type hints.
We now support Date to Long, Date to ObjectId, Script to String and other conversions for both reading and writing scenarios. Original pull request: #773.
This commit is contained in:
committed by
Mark Paluch
parent
2365dba8d9
commit
0a0ee417ac
@@ -15,8 +15,12 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.convert;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import static org.springframework.data.convert.ConverterBuilder.*;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Date;
|
||||
|
||||
import org.bson.types.Code;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
@@ -93,6 +97,21 @@ public abstract class AbstractMongoConverter implements MongoConverter, Initiali
|
||||
conversionService.addConverter(BigIntegerToObjectIdConverter.INSTANCE);
|
||||
}
|
||||
|
||||
if (!conversionService.canConvert(Date.class, Long.class)) {
|
||||
conversionService.addConverter(writing(Date.class, Long.class, Date::getTime).getWritingConverter());
|
||||
}
|
||||
|
||||
if (!conversionService.canConvert(Long.class, Date.class)) {
|
||||
conversionService.addConverter(reading(Long.class, Date.class, Date::new).getReadingConverter());
|
||||
}
|
||||
|
||||
if (!conversionService.canConvert(ObjectId.class, Date.class)) {
|
||||
|
||||
conversionService.addConverter(
|
||||
reading(ObjectId.class, Date.class, objectId -> new Date(objectId.getTimestamp())).getReadingConverter());
|
||||
}
|
||||
|
||||
conversionService.addConverter(reading(Code.class, String.class, Code::getCode).getReadingConverter());
|
||||
conversions.registerConvertersIn(conversionService);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.ConversionNotSupportedException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -1943,6 +1942,16 @@ public class MappingMongoConverterUnitTests {
|
||||
assertThat(target.get("script")).isEqualTo(new Code(source.script));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2328
|
||||
public void readsScriptAsStringWhenAnnotatedWithFieldTargetType() {
|
||||
|
||||
String reference = "if (a > b) a else b";
|
||||
WithExplicitTargetTypes target = converter.read(WithExplicitTargetTypes.class,
|
||||
new org.bson.Document("script", new Code(reference)));
|
||||
|
||||
assertThat(target.script).isEqualTo(reference);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1849
|
||||
public void mapsCollectionValueToExplicitTargetType() {
|
||||
|
||||
@@ -1968,6 +1977,96 @@ public class MappingMongoConverterUnitTests {
|
||||
assertThat(target.get("bigDecimal")).isEqualTo(new Decimal128(source.bigDecimal));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2328
|
||||
public void mapsDateToLongWhenAnnotatedWithFieldTargetType() {
|
||||
|
||||
WithExplicitTargetTypes source = new WithExplicitTargetTypes();
|
||||
source.dateAsLong = new Date();
|
||||
|
||||
org.bson.Document target = new org.bson.Document();
|
||||
converter.write(source, target);
|
||||
|
||||
assertThat(target.get("dateAsLong")).isEqualTo(source.dateAsLong.getTime());
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2328
|
||||
public void readsLongAsDateWhenAnnotatedWithFieldTargetType() {
|
||||
|
||||
Date reference = new Date();
|
||||
WithExplicitTargetTypes target = converter.read(WithExplicitTargetTypes.class,
|
||||
new org.bson.Document("dateAsLong", reference.getTime()));
|
||||
|
||||
assertThat(target.dateAsLong).isEqualTo(reference);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2328
|
||||
public void mapsLongToDateWhenAnnotatedWithFieldTargetType() {
|
||||
|
||||
Date date = new Date();
|
||||
WithExplicitTargetTypes source = new WithExplicitTargetTypes();
|
||||
source.longAsDate = date.getTime();
|
||||
|
||||
org.bson.Document target = new org.bson.Document();
|
||||
converter.write(source, target);
|
||||
|
||||
assertThat(target.get("longAsDate")).isEqualTo(date);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2328
|
||||
public void readsDateAsLongWhenAnnotatedWithFieldTargetType() {
|
||||
|
||||
Date reference = new Date();
|
||||
WithExplicitTargetTypes target = converter.read(WithExplicitTargetTypes.class,
|
||||
new org.bson.Document("longAsDate", reference));
|
||||
|
||||
assertThat(target.longAsDate).isEqualTo(reference.getTime());
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2328
|
||||
public void mapsStringAsBooleanWhenAnnotatedWithFieldTargetType() {
|
||||
|
||||
WithExplicitTargetTypes source = new WithExplicitTargetTypes();
|
||||
source.stringAsBoolean = "true";
|
||||
|
||||
org.bson.Document target = new org.bson.Document();
|
||||
converter.write(source, target);
|
||||
|
||||
assertThat(target.get("stringAsBoolean")).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2328
|
||||
public void readsBooleanAsStringWhenAnnotatedWithFieldTargetType() {
|
||||
|
||||
WithExplicitTargetTypes target = converter.read(WithExplicitTargetTypes.class,
|
||||
new org.bson.Document("stringAsBoolean", true));
|
||||
|
||||
assertThat(target.stringAsBoolean).isEqualTo("true");
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2328
|
||||
public void mapsDateAsObjectIdWhenAnnotatedWithFieldTargetType() {
|
||||
|
||||
WithExplicitTargetTypes source = new WithExplicitTargetTypes();
|
||||
source.dateAsObjectId = new Date();
|
||||
|
||||
org.bson.Document target = new org.bson.Document();
|
||||
converter.write(source, target);
|
||||
|
||||
// need to compare the the timestamp as ObjectId has an internal counter
|
||||
assertThat(target.get("dateAsObjectId", ObjectId.class).getTimestamp())
|
||||
.isEqualTo(new ObjectId(source.dateAsObjectId).getTimestamp());
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2328
|
||||
public void readsObjectIdAsDateWhenAnnotatedWithFieldTargetType() {
|
||||
|
||||
ObjectId reference = new ObjectId();
|
||||
WithExplicitTargetTypes target = converter.read(WithExplicitTargetTypes.class,
|
||||
new org.bson.Document("dateAsObjectId", reference));
|
||||
|
||||
assertThat(target.dateAsObjectId).isEqualTo(new Date(reference.getTimestamp()));
|
||||
}
|
||||
|
||||
static class GenericType<T> {
|
||||
T content;
|
||||
}
|
||||
@@ -1987,9 +2086,7 @@ public class MappingMongoConverterUnitTests {
|
||||
},
|
||||
SECOND {
|
||||
@Override
|
||||
void method() {
|
||||
|
||||
}
|
||||
void method() {}
|
||||
};
|
||||
|
||||
abstract void method();
|
||||
@@ -2416,7 +2513,20 @@ public class MappingMongoConverterUnitTests {
|
||||
@Field(targetType = FieldType.SCRIPT) //
|
||||
List<String> scripts;
|
||||
|
||||
@Field(targetType = FieldType.DECIMAL128) BigDecimal bigDecimal;
|
||||
@Field(targetType = FieldType.DECIMAL128) //
|
||||
BigDecimal bigDecimal;
|
||||
|
||||
@Field(targetType = FieldType.INT64) //
|
||||
Date dateAsLong;
|
||||
|
||||
@Field(targetType = FieldType.DATE_TIME) //
|
||||
Long longAsDate;
|
||||
|
||||
@Field(targetType = FieldType.BOOLEAN) //
|
||||
String stringAsBoolean;
|
||||
|
||||
@Field(targetType = FieldType.OBJECT_ID) //
|
||||
Date dateAsObjectId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user