关于mongodb-driver无法解析BigDecimal

背景:

springboot项目连接mongoDB数据库,在插入数据到mongDB时报错,异常消息显示没有BigDecimal的Codec。

原因:

跟随异常栈发现MongoDBDriver在转化数据是会从一个Codec注册表中获取相应java类的的Codec,然后重启项目跟随代码发现Codec注册表初始化时并没有添加BigDecimal的Codec,同时也没有BigDecimal的Codec

解决:

首先是实现Codec 创建 BigDecimal 的Codec:

public class MongoBigCodec implements Codec {

@Override

    public BigDecimaldecode(BsonReader bsonReader, DecoderContext decoderContext) {

            return new BigDecimal(bsonReader.readString());

    }

@Override

    public void encode(BsonWriter bsonWriter, BigDecimal bigDecimal, EncoderContext encoderContext) {

         bsonWriter.writeString(bigDecimal.toString());

    }

@Override

    public ClassgetEncoderClass() {  

             return BigDecimal.class;

    }

}

接着在spring初始化时,利用发射将实现的MongoBigCodec添加到Codec注册表:

@Component

public class MongoInitimplements CommandLineRunner {

@Autowired

    private MongoTemplatemongoTemplate;

    @Override

    public void run(String... strings)throws Exception {

Class clazz = (Class) (mongoTemplate.getDb().getMongo()).getClass();

        Field f = clazz.getDeclaredField("DEFAULT_CODEC_REGISTRY");

        f.setAccessible(true);

        CodecRegistry codecRegistry = (CodecRegistry) f.get(mongoTemplate.getDb().getMongo());

        Field cf = codecRegistry.getClass().getDeclaredField("codecProviders");

        cf.setAccessible(true);

        ValueCodecProvider codecProvider = (ValueCodecProvider) ((ArrayList) cf.get(codecRegistry)).get(0);

        Method[] putCs = codecProvider.getClass().getDeclaredMethods();

        Method putC =null;

        for (int i =0; i < putCs.length; i++) {

if (putCs[i].getName().equals("addCodec")) {

putC = putCs[i];

break;

            }

}

putC.setAccessible(true);

        putC.invoke(codecProvider, new MongoBigCodec());

    }

}

再次重启项目,程序能够正常的解析BigDecimal数据类型

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容