Save and load Guava Optional <?> S in MongoDB using Spring -Data
How to customize the display of Guava Optional(or later JDK8) using Spring -Data-MongoDb?
As an example, the following class should display as json below.
@Data
public class Test
{
Optional<String> stringOptionalNull = null;
Optional<String> stringOptionalAbsent = Optional.absent();
Optional<String> stringOptionalPresent = Optional.of("ExampleValue");
}
Json (Note: null and missing cases are handled in the same way):
{
"stringOptionalPresent" : "ExampleValue"
}
When they return again in java, nulland absentshould be translated to Optional.absent().
From Spring Data MongoDB Docs I read that org.springframework...Converterthis is the way to go. But with the API, I was not able to process the tags correctly null.
This is the full test version to reproduce the problem. It passes nulland verifies that the loaded object contains only Optional.absent().
public class OptionalMongoDbTest
{
@Data
@AllArgsConstructor
static class ClassWithOptionals
{
private final Optional<String> stringOptionalNull;
private final Optional<String> stringOptionalPresent;
private final Optional<String> stringOptionalAbsent;
}
public static class OptionalToStringConverter<T> implements Converter<Optional<T>, String>
{
@Override
public String convert(final Optional<T> arg0)
{
return arg0.isPresent() ? arg0.get().toString() : null;
}
}
public static class StringToOptionalConverter implements Converter<String, Optional<String>>
{
@Override
public Optional<String> convert(final String arg0)
{
return Optional.fromNullable(arg0);
}
}
@Test
public void persisted_object_should_be_equal() throws Exception
{
// Setup Mongodb connection
final SimpleMongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(new Mongo(), "test");
final MappingMongoConverter converter = new MappingMongoConverter(mongoDbFactory, new MongoMappingContext());
// Register Custom Converter
converter.setCustomConversions(new CustomConversions(Arrays.asList(new OptionalToStringConverter(), new StringToOptionalConverter())));
converter.afterPropertiesSet();
final MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory, converter);
mongoTemplate.setWriteConcern(WriteConcern.SAFE);
// Test the mapping
mongoTemplate.dropCollection(ClassWithOptionals.class);
final ClassWithOptionals objectToSave = new ClassWithOptionals(null, Optional.of("ExampleValue"), Optional.<String> absent());
mongoTemplate.save(objectToSave);
final ClassWithOptionals objectFromMongo = mongoTemplate.findAll(ClassWithOptionals.class).get(0);
// TODO: That test fails because there are null values comming from the databases
assertThat(objectFromMongo, is(new ClassWithOptionals(Optional.<String> absent(), Optional.of("ExampleValue"), Optional.<String> absent())));
}
}
, json, , :
{
"_id" : ObjectId("5343d8a5e4b0215d78a322d0"),
"stringOptionalPresent" : "ExampleValue",
"stringOptionalAbsent" : null // this line should be removed.
}
Edit
, , spring data mongo . - : https://github.com/spring-projects/spring-data-mongodb/blob/master/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java#L1037-L1041