Spring JPA原生查询与数据投影列映射错误问题问询
我之前刚上手JPA投影时也踩过一模一样的坑,结合你的情况,给你几个具体的排查点:
搞清楚接口方法名和列名的映射逻辑
JPA投影接口是通过方法名对应的属性名来匹配查询结果的,不是直接对应数据库列名。比如数据库列是accountnum,如果你的接口写的是getAccountnumber(),那对应的属性名是accountnumber,JPA找不到匹配的列自然会映射失败。
解决办法:要么把接口方法改成getAccountnum()直接匹配列名;如果坚持要用getAccountnumber(),可以在查询语句里给列加别名:SELECT accountnum AS accountnumber FROM ...,或者用@SqlResultSetMapping配合@ColumnResult指定映射关系。注意原生SQL和JPQL的差异
如果你的@Query用了nativeQuery=true(原生SQL),列名的匹配是严格对应查询返回的列名(包括别名);如果是JPQL,那你要写的是实体类的属性名,而不是数据库列名,投影接口的方法名要匹配实体类属性的getter方法。
举个原生SQL的正确例子:@Repository public interface AccountRepository extends JpaRepository<Account, Long> { @Query(value = "SELECT accountnum AS accountnumber, balance FROM user_account WHERE id = ?1", nativeQuery = true) AccountProjection findProjectionById(Long id); }这里的别名
accountnumber就对应接口的getAccountnumber()方法。检查投影接口的写法规范
投影接口必须是纯Getter接口,不能包含字段、构造方法或者其他业务方法,比如这样才是正确的:public interface AccountProjection { String getAccountnumber(); // 对应查询结果里的accountnumber列/别名 BigDecimal getBalance(); }警惕大小写敏感问题
有些数据库(比如PostgreSQL)是严格区分列名大小写的,如果你的数据库列是AccountNum,但查询里写的是accountnum,或者接口方法是getaccountnum(),都会导致映射失败,要确保三者的大小写一致。
内容的提问来源于stack exchange,提问作者Roddy of the Frozen Peas

