Spring Boot Data中MongoDB嵌套对象投影报错的问题与解决
问题分析与解决方案
你的getDto写法本身存在问题,核心原因是Spring Data MongoDB在映射嵌套对象的类投影时,需要明确指定要返回的字段,否则无法正确实例化嵌套对象,导致构造函数参数为null。无嵌套时正常是因为单一字段的映射逻辑更简单,不需要额外的嵌套结构解析。
可行的修改方案
方案1:在@Query中明确指定投影字段
修改Repository方法,添加fields参数指定要返回的字段(包括嵌套对象),让MongoDB只返回需要的数据,同时帮助Spring Data正确映射嵌套结构:
interface OuterRepository: MongoRepository<OuterDocument, String> { @Query(value = "{id: ?0}", fields = "{id: 1, nested: 1}") fun getDto(id: String): OuterDto? }
fields = "{id: 1, nested: 1}"表示只返回id和nested字段,这样Spring Data就能正确将MongoDB返回的nested子文档转换为NestedDocument实例,进而成功构造OuterDto。
方案2:使用接口式投影(推荐)
Spring Data推荐用接口投影处理字段子集查询,尤其是嵌套结构,不需要手动编写DTO类,Spring会自动生成代理类处理映射:
// 定义投影接口 interface OuterProjection { fun getId(): String fun getNested(): NestedProjection } interface NestedProjection { fun getNestedFoo(): String } // 修改Repository方法 interface OuterRepository: MongoRepository<OuterDocument, String> { @Query("{id: ?0}") fun getProjection(id: String): OuterProjection? }
这种方式更简洁,避免了类构造函数的匹配问题,同时支持灵活的字段选择。
方案3:调整DTO类的构造函数(可选)
如果坚持使用类DTO,可以给NestedDocument添加无参构造函数(Kotlin Data Class默认没有,需要手动添加或用注解),确保Spring Data能实例化嵌套对象:
data class NestedDocument( val nestedFoo: String ) { // 手动添加无参构造 constructor() : this("") } // 或者用Lombok注解(需要引入Lombok依赖) @NoArgsConstructor(force = true) data class NestedDocument( val nestedFoo: String )
不过这种方案优先级低于前两种,因为核心问题还是字段投影的明确性,而非构造函数本身。
内容的提问来源于stack exchange,提问作者AwesomeTown
相关产品推荐
相关产品推荐

