java spring data mongo不能pikup自定义ZonedDateTime转换器,为什么?

eh57zj3b  于 2023-06-28  发布在  Java
关注(0)|答案(2)|浏览(115)

我的问题就像这样CodecConfigurationException when saving ZonedDateTime to MongoDB with Spring Boot >= 2.0.1.RELEASE
但是我写了一个自定义的ZonedDateTime转换器:
ZonedDateTimeToDateConverter

@WritingConverter
public class ZonedDateTimeToDateConverter implements Converter<ZonedDateTime, Date> {
    @Override
    public Date convert(ZonedDateTime source) {
        if (source == null) {
            return null;
        }
        return Date.from(source.toInstant());
    }
}

DateToZonedDateTimeConverter

@ReadingConverter
public class DateToZonedDateTimeConverter implements Converter<Date, ZonedDateTime> {
    @Override
    public ZonedDateTime convert(Date source) {
        if (source == null) {
            return null;
        }
        return ZonedDateTime.ofInstant(source.toInstant(), ZoneId.of("UTC"));
    }
}

我的测试:

@Autowired
ReactiveMongoOperations operations;

@Test
void test() {
    ObjectId id = new ObjectId();

    Document doc = new Document();
    doc.append("_id", id);
//    doc.append("a", ZonedDateTime.now()); // works
    doc.append("zd1", new Document("f", ZonedDateTime.now())); // not working

    operations.insert(doc, "test-collection").block();

    Document found = Mono.from(operations.getCollection("test-collection")
            .find(new Document("_id", id)).first()).block();

    Assertions.assertNotNull(found);
}

如果我将一个ZDT示例添加到文档第一级,如doc.append("a", ZonedDateTime.now())-document保存良好。但是,如果我将一个ZDT示例作为嵌套字段(嵌套的第二层)放置到文档中,我会收到一个异常:
org. bson. codecs. configuration. CodecConfigurationException:找不到java.time.ZonedDateTime类的编解码器。
我做错了什么?

zi8p0yeb

zi8p0yeb1#

我通过将转换器添加到自定义转换器配置来解决类似的问题:

@Configuration
public class MongoCustomConverterConfig {

    @Bean
    public MongoCustomConversions mongoCustomConversions(){
        List<Converter<?,?>> converters = new ArrayList<>();
        converters.add(new ZoneDateTimeWriteConverter());
        converters.add(new ZonedDateTimeReadConverter());
        return new MongoCustomConversions(converters);
    }
}
5m1hhzi4

5m1hhzi42#

我完全避免使用Date或ZonedDateTime,而是使用了一个自定义类型,它 Package 了LocalDateTime,并使用它转换为DB的字符串。这可以防止MongoDB转换为UTC,同时将LocalDateTime的自定义类型留在业务级别进行转换和比较。您需要有一个单独的时区属性。这样,当比较或移动到另一个本地时间时,您可以在演示级别或类似级别创建一个新的ZonedDateTime。为了做到这一点,我使用了Chamindu在his site中描述的技术。只要确保扩展AbstractMongoClientConfiguration而不是AbstractMongoConfiguration。如果使用带有datetime-local的HTML5表单(即带有thymeleaf:<input type="datetime-local" th:field="*{myDate}"/>),您需要更改Chamindu指示的字符串格式,以便DB匹配输入所需的内容。在HTML表单和Mongo DB中对我都有效的字符串格式是。“yyyy-MM-dd'T'HH:mm:ss”而不是“yyyy-MM-dd'T'HHss.SSS”。注意:我不确定自定义类型如何影响验证和其他功能。

相关问题