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

为什么Spring Data MongoDB调用slice(String, int, int)会抛出异常?

问题根因

你遇到的异常是Spring Data MongoDB对应版本的已知缺陷导致,和你的配置无关:

  1. 你使用的Spring Boot 2.5.4对应Spring Data MongoDB 3.2.x版本,该版本Field.slice(String field, int offset, int size)方法的实现存在问题:内部将offset、size参数封装为Integer[]数组存入投影参数,但MongoDB Java驱动的默认BSON编解码器没有提供Java数组类型的序列化支持,仅支持List、基本数据类型、BSON原生类型,因此直接抛出找不到[Ljava.lang.Integer对应编解码器的异常。
  2. 你自定义的转换器没有生效是因为:Spring Data MongoDB的自定义转换器默认仅处理实体属性和BSON之间的序列化/反序列化,而查询构造阶段的投影参数序列化直接走MongoDB驱动的编解码器链路,不会经过MappingMongoConverter的自定义转换逻辑,因此你添加的转换器对slice参数无效。
解决方案

你可以根据自己的场景选择以下任意一种方案解决:

  • 方案一:升级Spring Boot版本到2.6.0及以上
    该版本对应的Spring Data MongoDB已经修复了该bug,slice方法内部会将参数封装为List<Integer>而非Integer[],完全兼容驱动的编解码器,不需要修改任何业务代码即可正常运行。
  • 方案二:手动构造$slice投影,绕过原生slice方法
    如果你不方便升级版本,可以直接手动写投影逻辑:
    Query query = Query.query(criteria);
    // 手动构造$slice投影,传入List类型参数适配驱动编解码
    query.fields().put("subcategories", Arrays.asList("$slice", Arrays.asList(0, 1)));
    
  • 方案三:使用聚合查询实现切片
    也可以用聚合API实现同样的效果,聚合的slice方法不存在该bug:
    Aggregation aggregation = Aggregation.newAggregation(
        Aggregation.match(Criteria.where("_id").is(new ObjectId("5a3931f6d60180000f16db8c"))),
        Aggregation.project().and("subcategories").slice(0, 1)
    );
    List<Category> result = mongoTemplate.aggregate(aggregation, Category.class, Category.class).getMappedResults();
    

内容的提问来源于stack exchange,提问作者Alex Formella

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 02:24:03