Java 8 Date/Time (JSR-310) types mapping with Spring Data MongoDB

java, java-8, java-time, spring-data, spring-data-mongodb

Solution

I don't know if this is the best way but I added Java 8 Date/Time (JSR-310) types support to Spring Data MongoDB `1.5.0.RELEASE` like this:

First step. Add simple Spring `Converter`s

public class InstantToLongConverter implements Converter<Instant, Long> {
    @Override
    public Long convert(Instant instant) {
        return instant.toEpochMilli();
    }
}

public class LongToInstantConverter implements Converter<Long, Instant> {
    @Override
    public Instant convert(Long source) {
        return Instant.ofEpochMilli(source);
    }
}

public class LocalDateToStringConverter implements Converter<LocalDate, String> {
    @Override
    public String convert(LocalDate localDate) {
        return localDate.toString();
    }
}

public class StringToLocalDateConverter implements Converter<String, LocalDate> {
    @Override
    public LocalDate convert(String source) {
        return LocalDate.parse(source);
    }
}

Second step. Register these custom `Converter`s with `MappingMongoConverter` in your `AbstractMongoConfiguration` implementation like this:

@Configuration
@EnableMongoRepositories(basePackages = {"my.app.repository"})
public class MongoConfiguration extends AbstractMongoConfiguration {

    ...

    @Override
    public CustomConversions customConversions() {
        return new CustomConversions(Arrays.asList(
                new InstantToLongConverter(), new LongToInstantConverter(),
                new LocalDateToStringConverter(), new StringToLocalDateConverter()));
    }
}

Now your document's `Instant` fields will be persisted as long values and `LocalDate`s as Strings.

Problem

I have simple document with Java 8 date/time fields ``` @Document public class Token { private Instant createdAt; ... } ``` that I want to persist with Spring Data MongoDB version 1.5. But fields of type `java.time.Instant` could not be de-serialized correctly because `MappingMongoConverter` lacks converters for `java.time` classes. In Spring 4 I found `org.springframework.format.datetime.standard.DateTimeConverters` with different `Converter`s including `InstantToLongConverter` and `LongToInstantConverter` declared as private static classes. How can I configure `MongoTemplate` to use them to map `Instant` fields to longs?

Original source