#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 нет часового пояса. У вас есть две альтернативы:
- Используйте тип данных Java, который поддерживает часовой пояс, для поля аудита, которое я бы выбрал
Instant
. - Например, используйте формат даты 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]