Spring Boot版本从2.4.13升级到2.5.14后的mongo聚合问题

问题描述 投票:0回答:1

在 Spring Boot 版本升级之前,聚合工作正常。升级到 2.5.14 后,我遇到 MongoTemplate.aggregate(Aggregationgregation, Class inputType, Class outputType) 的问题:

org.springframework.data.mapping.MappingException: Cannot convert [] of type class java.util.ArrayList into an instance of class java.lang.String! Implement a custom Converter<class java.util.ArrayList, class java.lang.String> and register it with the CustomConversions.
spring-boot spring-data-mongodb mappingexception
1个回答
0
投票

我最近在从 Spring Boot 2.4 升级到 Spring Boot 2.5 时遇到了这个问题(我相信是 Spring Data MongoDB 3.1.5 到 3.2)

我正在

无法将 java.util.ArrayList 类型的 [0] 转换为 java.math.BigDecimal 类的实例

我继续升级,Spring Boot 2.6,然后是 Spring Boot 2.7,确信新版本会修复该错误。

当这不起作用时,我花了几个小时进行搜索,但无法在任何地方找到导致先前工作查询中断的原因的解释。在我的研究中,我发现对 MappingMongoConverter 进行了许多更改,其中之一暴露了我的查询中的明显缺陷。

假设您正在尝试填充 ArrayList

public class MyClass {
    private long a;
    private BigDecimal b;
    private BigDecimal c;
}

你有一个像这样的聚合组:

Aggregation.group("a").sum("b").as("b").addToSet("c").as("c");

在这个聚合组中,我试图获取按“a”分组的“b”的总和,其中“c”在每个“a”组中的所有行上都是相同的,所以我只需要添加它即可。

如果手动运行查询,使用 $addToSet 时您将看到从 MongoDB 返回的原始 JSON,如下所示:

{
    "a" : NumberLong(0),
    "b" : NumberDecimal("1"),
    "c" : [ NumberDecimal("2") ]
}

显然 $push 和 $addToSet (也许还有其他)创建一个数组并将请求的值添加到数组中。

旧的 MappingMongoConverter 通过从“c”数组中获取第一个值来填充 MyClass。新的 MappingMongoConverter 并不那么宽容,它会给你一个错误,告诉你你正在尝试将 ArrayList 转换为单个值

我的解决方法是将我的聚合组更改为在“c”上使用 $first 而不是:

Aggregation.group("a").sum("b").as("b").first("c").as("c");

现在我从查询返回的原始 JSON 看起来像这样:

{
    "a" : NumberLong(0),
    "b" : NumberDecimal("1"),
    "c" : NumberDecimal("2")
}

我不再收到“无法转换 ArrayList”错误。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.