Pregunta Mapeo de tipos Java 8 Fecha / Hora (JSR-310) con Spring Data MongoDB


Tengo un documento simple con campos de fecha / hora de Java 8

@Document
public class Token {
    private Instant createdAt;
    ...
}

que quiero persistir con Spring Data MongoDB versión 1.5. Pero campos de tipo java.time.Instant no se pudo deserializar correctamente porque MappingMongoConverter carece de convertidores para java.time clases

En la primavera 4 encontré org.springframework.format.datetime.standard.DateTimeConverters con diferente Converters incluido InstantToLongConverter y LongToInstantConverter declarados como clases privadas estáticas.

¿Cómo puedo configurarlo? MongoTemplate usarlos para mapear Instant campos para anhelar?


10
2018-05-31 16:00


origen


Respuestas:


No sé si esta es la mejor manera, pero agregué el soporte de Java 8 Fecha / Hora (JSR-310) a Spring Data MongoDB 1.5.0.RELEASE Me gusta esto:

  1. Primer paso. Añadir simple primavera Converters

    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. Segundo paso. Registra estas personalizaciones Converters con MappingMongoConverter en tus AbstractMongoConfiguration implementación como esta:

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

Ahora su documento Instant los campos se mantendrán como valores largos y LocalDates como cadenas.


13
2018-06-01 17:57



@ user882209 lo explicó todo perfectamente.
Desde Spring Data MongoDB 1.7, se ha agregado el soporte para JSR-310.
Si la aplicación está respaldada por Spring Boot, todas las versiones anteriores a la 1.2.8 también la contendrían.
En una aplicación Spring Boot-ed puedes hacerlo de la siguiente manera:

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

Los siguientes convertidores son proporcionados por Jsr310Converters clase:
DateToLocalDateTimeConverter - LocalDateTimeToDateConverter DateToLocalDateConverter - LocalDateToDateConverter DateToLocalTimeConverter - LocalTimeToDateConverter DateToInstantConverter - InstantToDateConverter


3
2018-02-01 17:48