Spring JPA原生查询DTO接收字段为空及映射错误求助
问题原因分析
你的问题核心是原生SQL查询返回的列名存在重复,导致Spring JPA的TupleConverter无法正确映射到DTO接口:
- SQL中
E.name、C.name、T.name三个字段都返回相同的列名name - 投影接口
ExpenseDTO的getName()、getCategory()、getTimestamp()需要对应不同的列,但转换器无法区分重名的name列,最终出现字段覆盖(E.name被T.name覆盖)、未匹配字段返回null的情况
解决方案
给SQL中重复的字段添加别名,让别名和DTO接口的方法名(去掉get后的部分)一一对应:
修改仓库接口的@Query SQL:
@Repository public interface ExpenseRepository extends JpaRepository<Expense, Long> { @Query(value = """ SELECT E.name AS name, E.amount, C.name AS category, E.description, T.name AS timestamp FROM expense E INNER JOIN category C ON C.id = E.category_id INNER JOIN timestamp T ON T.id = E.timestamp_id """, nativeQuery = true) List<ExpenseDTO> getAll(); }
原理说明
Spring Data JPA的投影接口(如ExpenseDTO)是通过返回列名(别名)与方法名匹配来实现映射的:
- 列名
name对应getName() - 列名
category对应getCategory() - 列名
timestamp对应getTimestamp() - 列名
amount、description分别对应getAmount()、getDescription()
添加别名后,SQL返回的列名与DTO方法完全匹配,TupleConverter就能正确将每个字段值映射到对应的方法,解决字段混乱和null的问题。
内容的提问来源于stack exchange,提问作者AleXeNoN
相关产品推荐
相关产品推荐

