升级SpringBoot与MongoDB驱动后查询数据遇MappingException问题
我之前在升级Spring Boot到2.0版本时也碰到过几乎一模一样的MongoDB映射错误,结合你的代码和日志来看,问题根源在于Spring Data MongoDB 2.x(对应Spring Boot 2.0)对泛型嵌套集合的映射逻辑比1.x版本更严格。
问题分析
你的Positions类里的coordinates是三层嵌套的List<List<List<Double>>>,对应MongoDB里的三维数组结构。在Spring Data MongoDB 1.x(Spring Boot 1.3配套版本)中,框架会自动推断最内层数组的类型并转换成List<Double>,但升级到2.x后,框架在解析泛型时,无法自动将MongoDB返回的ArrayList(最内层的坐标数组)正确映射到List<Double>,反而试图把它转换成Object,从而抛出了MappingException。
解决方案
这里有两种可行的解决办法,推荐第二种更简洁的方案:
方案1:自定义类型转换器(通用解决嵌套集合映射)
你可以实现一个自定义的Converter,将MongoDB返回的数组类型(比如BasicDBList或ArrayList)转换成List<Double>,然后注册到Spring的Mongo转换配置中:
- 编写自定义转换器:
import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.ReadingConverter; import java.util.ArrayList; import java.util.List; @ReadingConverter public class ArrayListToDoubleListConverter implements Converter<Object, List<Double>> { @Override public List<Double> convert(Object source) { if (source instanceof ArrayList) { List<Double> result = new ArrayList<>(); for (Object item : (ArrayList<?>) source) { if (item instanceof Number) { result.add(((Number) item).doubleValue()); } } return result; } return null; } }
- 配置MongoTemplate的CustomConversions:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import java.util.Arrays; @Configuration public class MongoConfig { @Bean public MongoCustomConversions mongoCustomConversions() { return new MongoCustomConversions(Arrays.asList(new ArrayListToDoubleListConverter())); } }
这个转换器会在框架读取MongoDB数据时,自动把最内层的数组转换成List<Double>,解决类型不匹配的问题。
方案2:改用Spring Data MongoDB的GeoJSON类型(更推荐)
你的Positions结构完全符合GeoJSON的Polygon规范,Spring Data MongoDB 2.x已经内置了对GeoJSON类型的支持,直接使用GeoJsonPolygon类型可以省去自定义转换器的麻烦:
- 修改你的实体类:
import org.springframework.data.mongodb.core.geo.GeoJsonPolygon; public class Positions { private String type = "Polygon"; private GeoJsonPolygon coordinates; // 注意:这里的getter/setter要对应GeoJsonPolygon类型 public GeoJsonPolygon getCoordinates() { return coordinates; } public void setCoordinates(GeoJsonPolygon coordinates) { this.coordinates = coordinates; } public String getType() { return type; } public void setType(String type) { this.type = type; } }
GeoJsonPolygon会自动适配MongoDB里的Polygon坐标结构,Spring Data MongoDB会直接完成映射,不需要额外配置,这也是官方推荐的处理地理空间数据的方式。
验证
不管用哪种方案,重新启动应用后,查询MongoDB数据时应该就能正常映射coordinates字段,不会再抛出MappingException了。
内容的提问来源于stack exchange,提问作者Kiran Mungekar

