Spring Data JDBC嵌套DTO属性未填充的Repository问题排查
核心原因
Spring Data JDBC不会自动把关联查询返回的字段映射到嵌套DTO里,尤其是用Java Record作为DTO时,必须让查询结果的列名和嵌套对象的属性路径对应上,否则只会填充顶级属性,嵌套的users会是null或者未赋值状态。
常见问题及修复方法
查询语句未给嵌套字段加对应别名
比如你原来的查询可能直接返回了u.id、u.username这类字段,Spring Data JDBC会尝试把它们映射到ProjectsDto的顶级属性,而非嵌套的UsersDto。需要给这些字段加别名,用.指明嵌套路径:@Query("SELECT p.id, p.name, u.id AS users_id, u.username AS users_username FROM projects p JOIN users u ON p.user_id = u.id WHERE p.id = :id") ProjectsDto findProjectWithUserById(Long id);这里的
users_id对应ProjectsDto中users属性的id字段,users_username对应users的username字段,这样Spring Data JDBC就能正确识别并填充嵌套对象。Record构造器参数不匹配
Java Record是通过构造器初始化的,要保证查询返回的列顺序(或别名)和ProjectsDto、UsersDto的构造器参数完全对应。比如你的Record定义是:public record ProjectsDto(Long id, String name, UsersDto users) {} public record UsersDto(Long id, String username) {}那查询返回的列必须按
id, name, users_id, users_username的顺序返回,或者别名严格匹配参数名(开启参数名匹配后)。可选:开启参数名匹配
如果不想写别名,可以在配置文件里开启参数名匹配:spring.data.jdbc.repositories.named-parameters.enabled=true但这种方式对嵌套对象的支持不如别名可靠,还是推荐用别名明确映射。
Repository本身的验证
如果你的Repository只是定义了带@Query的查询方法,语法上没有错误的话,问题基本不在Repository结构本身,而是查询结果和DTO的映射匹配问题。正确的Repository示例参考上面的代码片段。
内容的提问来源于stack exchange,提问作者Thomas Lang

