Какие преобразователи следует использовать для LastModifiedDate, так как это вызывает ошибку исключения UnsupportedTemporalTypeException

#spring-boot #elasticsearch #spring-data-elasticsearch

Вопрос:

 @Builder.Default
@LastModifiedDate
@Field(type = FieldType.Date, name = "mdt", format = DateFormat.basic_date_time)
private LocalDateTime modifiedDate = LocalDateTime.now();

21-06-08T19:10:25,367 TRACE [http-nio-5555-exec-1] c.p.m.e.GlobalExceptionHandler: Found generic exception
java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: OffsetSeconds
        at java.base/java.time.LocalDate.get0(LocalDate.java:709)
        at java.base/java.time.LocalDate.getLong(LocalDate.java:688)
        at java.base/java.time.LocalDateTime.getLong(LocalDateTime.java:721)
        at java.base/java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:308)
        at java.base/java.time.format.DateTimeFormatterBuilder$OffsetIdPrinterParser.format(DateTimeFormatterBuilder.java:3569)
        at java.base/java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2343)
        at java.base/java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1847)
        at java.base/java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1821)
        at org.springframework.data.elasticsearch.core.convert.ElasticsearchDateConverter$PatternDateFormatter.format(ElasticsearchDateConverter.java:261)
 

Ответ №1:

Не имеет прямого отношения к ответу: это @LastModifiedDate аннотация из org.springframework.data.annotation пакета? И используете ли вы аудит эластичного поиска данных Spring (см. Документы)? Вам не нужно самостоятельно устанавливать значение поля. Если вы не используете аудит, вы можете удалить аннотацию.

На ваш вопрос: Формат DateFormat.basic_date_time -это дата с указанием времени и часового пояса. Но LocalDateTime у a нет часового пояса. У вас есть две альтернативы:

  1. Используйте тип данных Java, который поддерживает часовой пояс, для поля аудита, которое я бы выбрал Instant .
  2. Например, используйте формат даты Elasticsearch, в котором не ожидается часовой DateFormat.date_hour_minute_second_millis пояс . Вам нужно воссоздать свой индекс с помощью сопоставления, если вы измените его.

Лично я бы выбрал первое.

Ответ №2:

Наконец, я нахожу ответ на этот вопрос, так как @p-j-meisch упомянул LocalDateTime зону «Не поддерживает», что приведет к проблеме с форматом.

Я перепробовал несколько решений, но не нашел основной причины, пока не создал пример метода, чтобы выяснить, что происходит LocalDateTime и в каком формате следует использовать, как вы видите в приведенных ниже журналах, и закодируйте правильный формат, когда вам интересно встречаться со временем, лучший date_hour_minute_second_millis формат или date_hour_minute_second_fraction зависит от вас.

 fun main(args: Array<String>) {
    DateFormat.values().map {
        try {
            val elasticsearchDateConverter = ElasticsearchDateConverter.of(it)
            val format = elasticsearchDateConverter.format(LocalDateTime.now())
            val parsedValue = elasticsearchDateConverter.parse(format, LocalDateTime::class.java)
            Pair(true, " $it  Working fine --> [formatter: $format ] [parser: $parsedValue]")
        } catch (e: Exception) {
            Pair(false, " $it Not-Supported [error = ${e.message}]")
        }
    }.filter { it.first }
     .forEach {
        println(it.second)
     }
}

 

результат приведенного выше кода:

  date_hour  Working fine --> [formatter: 2021-06-13T22 ] [parser: 2021-06-13T22:00]
 date_hour_minute  Working fine --> [formatter: 2021-06-13T22:51 ] [parser: 2021-06-13T22:51]
 date_hour_minute_second  Working fine --> [formatter: 2021-06-13T22:51:47 ] [parser: 2021-06-13T22:51:47]
 date_hour_minute_second_fraction  Working fine --> [formatter: 2021-06-13T22:51:47.644 ] [parser: 2021-06-13T22:51:47.644]
 date_hour_minute_second_millis  Working fine --> [formatter: 2021-06-13T22:51:47.645 ] [parser: 2021-06-13T22:51:47.645]