Spring Data MongoDB自定义ReactiveMongoTemplate聚合结果无法映射DTO
问题根因
你自定义的ReactiveMongoQueryTemplate没有注入Spring Data MongoDB默认的MappingMongoConverter,直接初始化的模板仅使用极简转换器,不支持以下默认映射能力:
- 自动将Mongo返回的
_id字段映射到Java类的id字段 - 自动完成Mongo
ISODate类型到JavaOffsetDateTime类型的转换
映射失败的元素会被响应式流静默过滤,因此不会抛出错误也没有返回结果。
另外你的Java代码中排序规则和原生Mongo语句相反,会导致分组取到的last值不符合预期,不属于映射失效的原因但需要修正。
解决方案
1. 修正自定义MongoTemplate配置
给自定义模板注入官方提供的映射转换器,保留默认的映射、类型转换能力:
@Configuration class MultipleMongoConfig { private final CustomMongoProperties customMongoProperties; // 注入Spring自动配置好的映射转换器 private final MappingMongoConverter mappingMongoConverter; public MultipleMongoConfig(CustomMongoProperties customMongoProperties, MappingMongoConverter mappingMongoConverter) { this.customMongoProperties = customMongoProperties; this.mappingMongoConverter = mappingMongoConverter; } @Bean public MongoClient reactiveMongoQueryClient() { return MongoClients.create(createMongoClientSettings(customMongoProperties.getQuery())); } @Bean("mongoQueryTemplate") public ReactiveMongoTemplate reactiveMongoQueryTemplate() { ReactiveMongoTemplate template = new ReactiveMongoTemplate(reactiveMongoQueryClient(), customMongoProperties.getQuery().getDatabase()); // 给模板设置映射转换器 template.setConverter(mappingMongoConverter); return template; } private MongoClientSettings createMongoClientSettings(MongoProperties mongoProperties) { ConnectionString connectionString = new ConnectionString(mongoProperties.getUri()); return MongoClientSettings.builder() .readConcern(ReadConcern.DEFAULT) .writeConcern(WriteConcern.MAJORITY) .readPreference(ReadPreference.primary()) .applyConnectionString(connectionString) .build(); } }
如果你定义的
ReactiveMongoQueryTemplate是继承ReactiveMongoTemplate的自定义子类,确保父类的setConverter方法没有被重写屏蔽。
2. DTO增加显式字段映射(可选兜底)
可以给DTO字段加@Field注解显式指定映射关系,避免配置异常导致的映射失败:
@Data @Builder @NoArgsConstructor @AllArgsConstructor public class ProjectionProperty { @Field("_id") private String id; private String value; private OffsetDateTime issuedAt; }
3. 修正排序规则
将Java代码中的排序规则调整为和原生Mongo语句一致:
Aggregation.sort(Direction.ASC, PRIORITY) .and(Direction.DESC, ISSUED_AT)
调试技巧
如果后续再遇到类似无返回无报错的问题,可以先将聚合结果转为org.bson.Document类型打印原始返回,确认数据已经正常从Mongo查询返回,再定位映射环节问题:
reactiveMongoQueryTemplate.aggregate(aggregation, Document.class) .doOnNext(doc -> System.out.println("原始返回结果:" + doc)) .collectList();
内容的提问来源于stack exchange,提问作者Bert Roex
相关产品推荐
相关产品推荐

