简体   繁体   中英

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

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?

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:

  1. 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); } } 
  2. 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.

@user882209 explained it all just perfectly.
Since Spring Data MongoDB 1.7 the support for JSR-310 has been added.
If application is backed by Spring Boot every version over 1.2.8 would contain it as well.
In a Spring Boot-ed app you can just do it the following:

@Configuration
public class MongoDbConfig {

    @Autowired
    private MongoDbFactory mongoDbFactory;

    @Bean
    public MongoTemplate mongoTemplate() {
        MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory),
            new MongoMappingContext());
        converter.setCustomConversions(new CustomConversions(Arrays.asList(...)));

    return new MongoTemplate(mongoDbFactory, converter);
    }
}

The following converters are provided by the class: 类提供以下转换器:
DateToLocalDateTimeConverter - LocalDateTimeToDateConverter DateToLocalDateConverter - LocalDateToDateConverter DateToLocalTimeConverter - LocalTimeToDateConverter DateToInstantConverter - InstantToDateConverter

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM