Spring MongoTemplate limit(1)失效抛IncorrectResultSize异常问题
问题根因
你遇到的IncorrectResultSizeDataAccessException是Spring Data MongoDB的标准校验异常:findOne()方法要求查询结果最多只能有1条文档,只要返回结果≥2就会直接抛出这个错误。
从异常打印的Query信息Query: {}, Fields: {}, Sort: {}可以明确判断:你代码里给Query设置的排序、limit规则根本没有传到最终执行的查询里,问题和MongoDB服务本身无关,基本是注入实例错误或者Query写法的问题,和你提到的自动装配逻辑确实有关系。
修复步骤
- 先排查MongoTemplate注入问题
你提到代码从REST层挪到Service层才出问题,90%的概率是注入了错误的MongoTemplate实例:- 你Service层的变量名是
mongoDb,如果容器里存在多个MongoTemplate类型的Bean(比如自定义过MongoTemplate、多数据源配置),@Autowired会按变量名匹配Bean,很可能拿到了被AOP拦截、或者自定义逻辑有问题的实例。直接把变量名改成默认的mongoTemplate,确认注入的是官方自动配置的默认实例:@Autowired private MongoTemplate mongoTemplate; - 如果自己定义过MongoTemplate的Bean,检查自定义代码里有没有重写查询相关方法、有没有添加Query拦截器把排序、limit参数抹掉的逻辑。
- 你Service层的变量名是
- 修正Query构造逻辑
部分旧版本Spring Data MongoDB的Query链式方法存在坑:with(Sort)在部分版本会返回新的Query对象而不是修改原对象,你写的链式调用没有把返回值重新赋值给原query变量,会导致后续的limit、sort配置全部落在临时对象上,传给findOne的还是最开始new出来的空Query。改成显式逐行设置的写法,避免链式调用的隐式问题:public DetailedOrder findTheBiggestBy(String byWhat){ Query query = new Query(); // 确认导入的是org.springframework.data.domain.Sort,不要导错包 Sort sort = Sort.by(Sort.Direction.DESC, byWhat); query.with(sort); query.limit(1); // 临时加这行打印,确认执行前query已经带上了sort和limit System.out.println("执行查询:" + query); // 暂时替换findOne为find方法,直接取第一条结果,绕开findOne的多结果校验,同时验证limit是否生效 List<DetailedOrder> results = mongoTemplate.find(query, DetailedOrder.class); return results.isEmpty() ? null : results.get(0); } - 检查排序字段路径
如果要按嵌套对象BaseOrder里的字段排序,byWhat必须写全路径,比如按期望价格排序要传"baseOrder.desideredPrice",传错路径只会导致排序逻辑错误,不会导致limit失效,但也需要注意。
其他注意点
你的DetailedOrder类里同时导入了MongoDB原生驱动的@BsonId注解和Spring Data的@MongoId注解,不要混用两个序列化体系的注解,删掉没用的@BsonId导入即可,避免出现字段映射异常。
内容的提问来源于stack exchange,提问作者Pennesi Diego
相关产品推荐
相关产品推荐

