You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot PostgreSQL原生查询映射DTO报错:语法错误如何解决

问题原因

当设置nativeQuery=true时,你的SQL语句会直接发送给PostgreSQL执行,但SELECT new com.demo.project.dao.UserCommentsResponse(...)是HQL(Hibernate查询语言)特有的语法,PostgreSQL无法识别Java类的构造调用,因此抛出语法错误。

解决方案

方案1:改用HQL查询(去掉nativeQuery=true)

既然要使用DTO构造函数映射结果,直接用HQL更合适,Hibernate会自动处理DTO实例化。注意HQL中要使用实体类名和属性名,而非数据库表名和列名:

@Query(value="SELECT new com.demo.project.dao.UserCommentsResponse(p.placeName, c.text) FROM Comment c JOIN c.place p WHERE c.customer.id = :id")
List<UserCommentsResponse> getUsersComments(int id);
  • 假设你的实体类是Comment和Place,且Comment实体中有place关联属性,Customer实体是Comment的关联对象,customer.id对应数据库的customer_id列。
  • 确保DTO的构造函数参数顺序和HQL中选择的字段顺序完全一致。

方案2:使用原生SQL+@SqlResultSetMapping映射DTO

如果必须使用原生SQL,可以通过JPA的@SqlResultSetMapping和@ConstructorResult来指定结果集到DTO的映射:

步骤1:定义结果集映射

在任意实体类上添加@SqlResultSetMapping(比如在Comment实体类上):

@Entity
@SqlResultSetMapping(
    name = "UserCommentsResponseMapping",
    classes = @ConstructorResult(
        targetClass = UserCommentsResponse.class,
        columns = {
            @ColumnResult(name = "place_name", type = String.class),
            @ColumnResult(name = "text", type = String.class)
        }
    )
)
public class Comment {
    // 实体类其他代码
}

步骤2:修改原生查询

指定使用上述结果集映射:

@Query(
    value = "SELECT p.place_name as place_name, c.text as text FROM comment c INNER JOIN place p ON p.id = c.place_id WHERE c.customer_id = :id",
    nativeQuery = true,
    resultSetMapping = "UserCommentsResponseMapping"
)
List<UserCommentsResponse> getUsersComments(int id);
  • 原生SQL中要给字段起别名,和@ColumnResult中的name一致。
  • targetClass指定你的DTO类,columns的顺序要和DTO构造函数的参数顺序匹配。

方案3:使用Spring Data接口投影

创建一个投影接口,字段名和原生查询返回的列名(或别名)一致:

public interface UserCommentsProjection {
    String getPlaceName();
    String getText();
}

然后修改查询方法:

@Query(
    value = "SELECT p.place_name as placeName, c.text as text FROM comment c INNER JOIN place p ON p.id = c.place_id WHERE c.customer_id = :id",
    nativeQuery = true
)
List<UserCommentsProjection> getUsersComments(int id);
  • 接口的方法名要和查询结果的别名对应(比如placeName对应别名placeName),Spring Data会自动映射结果到接口实例。

内容的提问来源于stack exchange,提问作者Sercan Noyan Germiyanoğlu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 06:25:53