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

Java MongoDB驱动POJO编解码报错:找不到'Optional'公共构造函数

异常原因

你遇到的报错不是你的实体类CollectionOrProduct的构造函数有问题,本质是MongoDB默认的POJO编解码器不支持java.util.Optional类型的反序列化:

  • Optional是JDK提供的不可变容器类,没有公共无参构造函数,默认的PojoCodecProvider自动扫描模式下无法实例化该类型对象,因此抛出找不到公共构造函数的异常。
解决方法

有三种常用的解决方案,可按需选择:

方案1:替换属性类型(最简单通用)

直接把实体类的属性类型从Optional<List<SelectOptionModel>>改为List<SelectOptionModel>,业务侧需要使用Optional时,在getter方法里自行封装即可:

@Introspected
public class CollectionOrProduct {
    private List<SelectOptionModel> product;
    private List<SelectOptionModel> collection;

    public CollectionOrProduct() {
    }

    public CollectionOrProduct(List<SelectOptionModel> product, List<SelectOptionModel> collection) {
        this.product = product;
        this.collection = collection;
    }

    public Optional<List<SelectOptionModel>> getProduct() {
        return Optional.ofNullable(product);
    }

    public Optional<List<SelectOptionModel>> getCollection() {
        return Optional.ofNullable(collection);
    }

    public void setProduct(List<SelectOptionModel> product) {
        this.product = product;
    }

    public void setCollection(List<SelectOptionModel> collection) {
        this.collection = collection;
    }
}

不需要修改其他业务逻辑,也不需要调整编解码器配置。

方案2:注册Optional专用编解码器

如果必须保留属性为Optional类型,可以自定义Optional编解码器或者引入官方扩展的OptionalCodec,将其添加到你的编解码器注册表中:

// 先定义OptionalCodecProvider,或者直接引入第三方已经实现好的实现
public class OptionalCodecProvider implements CodecProvider {
    @Override
    public <T> Codec<T> get(Class<T> clazz, CodecRegistry registry) {
        if (clazz == Optional.class) {
            return (Codec<T>) new OptionalCodec(registry);
        }
        return null;
    }
}

// 修改你Repository中的CodecRegistry构造逻辑,提前注册Optional的编解码器
CodecRegistry pojoCodecRegistry = fromRegistries(
        MongoClientSettings.getDefaultCodecRegistry(),
        fromProviders(new OptionalCodecProvider()),
        fromProviders(PojoCodecProvider.builder().automatic(true).build())
);

如果你使用的是Spring Data MongoDB、Micronaut Data MongoDB等框架,高版本已经内置了Optional类型的编解码器支持,升级到对应版本后不需要自行实现。

方案3:标记字段忽略序列化

如果该字段不需要持久化到MongoDB,可以直接加@BsonIgnore注解忽略该字段的编解码处理,即可避开报错。


内容的提问来源于stack exchange,提问作者San Jaisy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 00:48:05