Хранить Java 8 мгновенно в качестве даты BSON с помощью SpringData-MongoDB
У меня есть следующий класс, который я хочу сохранить в MongoDB, используя Spring Datap >
@Document()
public class Tuple2<T extends Enum<T>> {
@Id
private String id;
@Indexed
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private final Instant timeCreated;
...
}
Дата аннотации DateTimeFormat javadoc:
Объявляет, что поле должно быть отформатировано как дата. Поддерживает форматирование по шаблону стиля, шаблону времени даты ISO или строке шаблона пользовательского формата. Может применяться к java.util.Date, java.util.Calendar, java.long.Long, типам значений Joda-Time; и с Spring 4 и JDK 8, для типов java.time JSR-310.
Я использую Spring 4.1.1 и JDK 8, поэтому я ожидаю, что это применимо к Instant
. Однако вот что на самом деле хранится:
"timeCreated" : {
"seconds" : NumberLong(1416757496),
"nanos" : 503000000
}
Если я пишу и регистрирую пользовательский преобразователь от Instant to Date, как описано в этом ответе, то он работает, однако я бы хотел этого избежать, поскольку я уверен должен быть лучший способ.
После дальнейшего копания в исходном коде Spring я нашел следующий класс Jsr310DateTimeFormatAnnotationFormatterFactory
, который выглядит многообещающим:
Форматирует поля, аннотированные аннотацией DateTimeFormat с использованием пакета java.time JSR-310 в JDK 8.
Его источник не ссылается на Instant
, но он ссылается на OffsetTime и LocalTime. Тем не менее, когда я изменяю Instant в качестве OffsetDateTime в моем примере, он по-прежнему сохраняется как составной объект вместо ISODate.
Что не хватает?
Ответы
Ответ 1
Я думаю, что проблема заключается в том, что вы пытаетесь использовать Instant
как время. Концептуально это точка временной шкалы, и это не означает форматирование.
Как мы знаем, Java 8 time API был разработан с глазу на joda-time (и с участием разработчиков joda-времени). Вот комментарий от joda-time Instant
:
Мгновенное действие должно использоваться для представления точки во времени независимо от любого другого фактора, например хронологии или часового пояса.
Поэтому нет возможности форматирования для org.joda.time.Instant
в JodaDateTimeFormatAnnotationFormatterFactory
, которая появилась в Spring с версии 3.0. А также он не был реализован в Jsr310DateTimeFormatAnnotationFormatterFactory
Итак, вы должны использовать пользовательский конвертер или считаете, что используете более подходящий класс.