You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot双MongoDB实例ZonedDateTime转换器配置失败

Spring Boot 2.7.6双MongoDB实例下ZonedDateTime序列化异常解决

问题场景

  • Spring Boot 2.7.6配置主从两个MongoDB实例,集合包含ZonedDateTime类型字段
  • 单库连接时,自定义MongoCustomConversions转换器可正常处理该类型
  • 双库配置后,保存数据抛出异常:

    org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class java.time.ZonedDateTime.

  • 尝试共用转换器配置,问题依旧
  • 项目Maven指定Java 1.8,运行在OpenJDK19的Docker容器中

当前配置代码

主库配置

@Bean
@Primary
@Override
public MongoCustomConversions customConversions() {
    List<Converter<?, ?>> converters = new ArrayList<>();
    converters.add(new MultipleMongoConfig.DateToZonedDateTimeConverter());
    converters.add(new MultipleMongoConfig.ZonedDateTimeToDateConverter());
    return new MongoCustomConversions(converters);
}

@Bean
@Primary
public MongoDatabaseFactory primaryFactory() throws Exception {
    return new SimpleMongoClientDatabaseFactory(((connection)));
}

@Primary
@Bean(name = "primaryMongoTemplate")
public MongoTemplate primaryMongoTemplate() throws Exception {     
    return new MongoTemplate(primaryFactory());
}

从库配置

@Bean(name = "secondaryMongoTemplate")
public MongoTemplate secondaryMongoTemplate() throws Exception {
    return new MongoTemplate(secondaryFactory());
}

@Bean    
@Override
public MongoCustomConversions customConversions() {
    List<Converter<?, ?>> converters = new ArrayList<>();
    converters.add(new MultipleMongoConfig.DateToZonedDateTimeConverter());
    converters.add(new MultipleMongoConfig.ZonedDateTimeToDateConverter());
    return new MongoCustomConversions(converters);
}

@Bean
public MongoDatabaseFactory secondaryFactory() throws Exception {
    return new SimpleMongoClientDatabaseFactory(((connection)));
}

YAML配置

main:
    allow-bean-definition-overriding: true

问题原因

  1. 双库配置时,直接通过MongoTemplate(MongoDatabaseFactory)构造实例,未将自定义的MongoCustomConversions绑定到对应的MappingMongoConverter中,导致MongoTemplate使用默认转换器,无法处理ZonedDateTime类型。
  2. 编译JDK版本(1.8)与运行JDK版本(19)不一致,可能引发Java时间类兼容性问题,加重序列化异常。

解决方案

1. 手动绑定自定义转换器到每个MongoTemplate

修改主库和从库的配置,通过MappingMongoConverter将自定义转换器关联到对应的MongoTemplate:

主库配置修改

@Bean
@Primary
public MongoCustomConversions primaryCustomConversions() {
    List<Converter<?, ?>> converters = new ArrayList<>();
    converters.add(new MultipleMongoConfig.DateToZonedDateTimeConverter());
    converters.add(new MultipleMongoConfig.ZonedDateTimeToDateConverter());
    return new MongoCustomConversions(converters);
}

@Bean
@Primary
public MappingMongoConverter primaryMappingMongoConverter(MongoDatabaseFactory primaryFactory, MongoCustomConversions primaryCustomConversions) throws Exception {
    MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(primaryFactory), new MongoMappingContext());
    converter.setCustomConversions(primaryCustomConversions);
    converter.afterPropertiesSet();
    return converter;
}

@Primary
@Bean(name = "primaryMongoTemplate")
public MongoTemplate primaryMongoTemplate(MongoDatabaseFactory primaryFactory, MappingMongoConverter primaryMappingMongoConverter) throws Exception {
    return new MongoTemplate(primaryFactory, primaryMappingMongoConverter);
}

@Bean
@Primary
public MongoDatabaseFactory primaryFactory() throws Exception {
    return new SimpleMongoClientDatabaseFactory(((connection)));
}

从库配置修改

@Bean(name = "secondaryCustomConversions")
public MongoCustomConversions secondaryCustomConversions() {
    List<Converter<?, ?>> converters = new ArrayList<>();
    converters.add(new MultipleMongoConfig.DateToZonedDateTimeConverter());
    converters.add(new MultipleMongoConfig.ZonedDateTimeToDateConverter());
    return new MongoCustomConversions(converters);
}

@Bean(name = "secondaryMappingMongoConverter")
public MappingMongoConverter secondaryMappingMongoConverter(MongoDatabaseFactory secondaryFactory, @Qualifier("secondaryCustomConversions") MongoCustomConversions secondaryCustomConversions) throws Exception {
    MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(secondaryFactory), new MongoMappingContext());
    converter.setCustomConversions(secondaryCustomConversions);
    converter.afterPropertiesSet();
    return converter;
}

@Bean(name = "secondaryMongoTemplate")
public MongoTemplate secondaryMongoTemplate(MongoDatabaseFactory secondaryFactory, @Qualifier("secondaryMappingMongoConverter") MappingMongoConverter secondaryMappingMongoConverter) throws Exception {
    return new MongoTemplate(secondaryFactory, secondaryMappingMongoConverter);
}

@Bean
public MongoDatabaseFactory secondaryFactory() throws Exception {
    return new SimpleMongoClientDatabaseFactory(((connection)));
}

2. 统一Java版本(推荐)

将编译和运行的Java版本统一,避免兼容性问题:

  • 若保留JDK8运行环境,修改Docker容器使用OpenJDK8镜像
  • 若升级到JDK19,修改pom.xml的编译版本:
<properties>
    <maven.compiler.source>19</maven.compiler.source>
    <maven.compiler.target>19</maven.compiler.target>
</properties>

3. 移除Bean覆盖配置

由于已经通过指定Bean名称(如primaryCustomConversions、secondaryCustomConversions)避免冲突,可以删除YAML中的main.allow-bean-definition-overriding: true,防止意外覆盖Bean定义。

验证

启动项目后,尝试保存包含ZonedDateTime字段的文档,检查是否正常完成序列化与反序列化,无CodecConfigurationException异常抛出。

内容的提问来源于stack exchange,提问作者Armen Arzumanyan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 09:00:41