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

Posted

技术标签:

【中文标题】spring data mongo 不能 pikup 自定义 ZonedDateTime 转换器,为啥?【英文标题】:spring data mongo can't pikup custom ZonedDateTime converter, why?spring data mongo 不能 pikup 自定义 ZonedDateTime 转换器,为什么? 【发布时间】:2020-04-30 00:34:24 【问题描述】:

我的问题是这样的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()) 这样的文档的第一级 - 文档保存得很好。但是,如果我将 ZDT 实例作为嵌套字段(第二级嵌套)放置到文档中,则会收到异常:

org.bson.codecs.configuration.CodecConfigurationException:找不到类 java.time.ZonedDateTime 的编解码器。

我做错了什么?

【问题讨论】:

【参考方案1】:

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

@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);
    

【讨论】:

以上是关于spring data mongo 不能 pikup 自定义 ZonedDateTime 转换器,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用 spring data mongo 插入 Mongo 文档

如何使用 mongo 搜索集合并返回子文档列表(Spring-data-mongo)

使用 Spring data mongo 和 Spring data elasticsearch 时如何建模?

使用 mongoTemplate 在 spring-data-mongo Java 中进行 Mongo 聚合查询

spring-data-mongo - 可选查询参数?

spring-data-mongo的MongoTemplate开发