使用 Spring Data Elasticsearch 定义自定义日期格式和转换器

2023-12-23

我目前正在从 Spring Data Elasticsearch 3.2.x 迁移到 4.0.0。

我正在删除一个JacksonEntityMapper,定义了一个自定义ZonedDateTimeDeserializer,使用ElasticsearchEntityMapper

我有一个 ZonedDateTime 字段定义如下:

    @Field(type = Date, format = DateFormat.date_time)
    private final ZonedDateTime loggedIn;

然而,这样的反序列化会丢失区域信息,因此存储前后的字段比较失败:

before

loggedIn=2020-06-01T09:50:27.389589+01:00[Europe/London]

after

loggedIn=2020-06-01T09:50:27.389+01:00

我预计区域信息会丢失,因为仅存储时区偏移量。与杰克逊ZonedDateTimeDeserializer我能够在 ZonedDateTime 构造期间应用区域。

理想情况下,我想定义自定义日期格式和转换器类来处理我的场景。

我尝试过以下字段配置:

    @Field(type = Date, format = DateFormat.custom, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ")
    private final ZonedDateTime loggedIn;

带读/写转换器

@WritingConverter
public class ZonedDateTimeToStringConverter implements Converter<ZonedDateTime, String>  {

    @Override
    public String convert(ZonedDateTime source) {
        return source.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
    }
}

@ReadingConverter
public class StringToZonedDateTimeConverter implements Converter<String, ZonedDateTime>  {

    @Override
    public ZonedDateTime convert(String source) {
        return ZonedDateTime.parse(source, DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(ZoneId.systemDefault()));
    }
}

和配置

public class ElasticConfiguration extends AbstractElasticsearchConfiguration {

    @Bean
    @Override
    public ElasticsearchCustomConversions elasticsearchCustomConversions() {
        return new ElasticsearchCustomConversions(List.of(new ZonedDateTimeToStringConverter(),
                                                          new StringToZonedDateTimeConverter()));
    }
}

但是,读取该字段失败,但出现异常

Caused by: java.time.DateTimeException: Unable to obtain LocalDate from TemporalAccessor: {YearOfEra=2020, MonthOfYear=8, DayOfMonth=20, OffsetSeconds=3600},ISO resolved to 11:11:11.123 of type java.time.format.Parsed
    at java.base/java.time.LocalDate.from(LocalDate.java:396)
    at java.base/java.time.ZonedDateTime.from(ZonedDateTime.java:560)
    at org.springframework.data.elasticsearch.core.convert.ElasticsearchDateConverter.parse(ElasticsearchDateConverter.java:109)
    at org.springframework.data.elasticsearch.core.convert.ElasticsearchDateConverter.parse(ElasticsearchDateConverter.java:114)
    ...

查看异常,将解析与成功进行比较时DateFormat.date_time阅读,我的模式可能有错误。 TemporalAccessor 的DateFormat.date_time is {OffsetSeconds=3600, InstantSeconds=1597918271},ISO resolved to 2020-08-20T11:11:11.123,而我的自定义模式解析为{YearOfEra=2020, MonthOfYear=8, DayOfMonth=20, OffsetSeconds=3600},ISO resolved to 11:11:11.123

但我指定的自定义转换器似乎也没有被选中。笔记。我指定了其他客户转换器正在被拾取,因此不认为这是配置问题。

任何帮助将不胜感激,我不确定为什么自定义模式失败,但我认为如果选择自定义转换器,我可以避免它。我现在可以解决这个问题,但理想情况下我希望升级前后一切都保持一致。


不要使用yyyy在日期模式中,将其更改为(请参阅Elasticsearch 文档 https://www.elastic.co/guide/en/elasticsearch/reference/current/migrate-to-java-time.html#java-time-migration-incompatible-date-formats)

pattern = "uuuu-MM-dd'T'HH:mm:ss.SSSSSSZ")

通过将属性定义为FieldType.Date在内部为此属性创建并使用转换器;不需要自定义转换器

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Spring Data Elasticsearch 定义自定义日期格式和转换器 的相关文章

随机推荐