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

SpringBoot/JPA按project_id排序触发PropertyReferenceException问题求助

问题分析与解决

问题场景

在SpringBoot/JPA(Postgres)项目中,定义了projects表:

create table projects(
 project_id int primary key,
 name varchar(255),
 description text
);

控制器中原本按name排序的列表接口正常运行:

@GetMapping("/list")
@ResponseBody
public Page<Project> list(@AuthenticationPrincipal UserDetails currentUserDetails) {
    int page = 0;
    int size = 100;
    Sort sort = Sort.by("name").ascending();
    PageRequest p = PageRequest.of(page, size, sort);

    return projectService.list(p);
}

但将排序字段改为project_id后:

Sort sort = Sort.by("project_id").ascending();

运行时抛出异常:

2024-01-01T14:34:04,424 ERROR [http-nio-8081-exec-6] o.a.j.l.DirectJDKLog: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.data.mapping.PropertyReferenceException: No property 'project' found for type 'Project'] with root cause
org.springframework.data.mapping.PropertyReferenceException: No property 'project' found for type 'Project'
at org.springframework.data.mapping.PropertyPath.(PropertyPath.java:90)

对应的Project实体类定义:

@Entity
@Table(name = "Projects")
public class Project {
@Id
@GeneratedValue(generator = "ProjectSeq")
@SequenceGenerator(name = "ProjectSeq", sequenceName = "PROJECTS_PROJECT_ID_SEQ", allocationSize = 1)
Integer project_id;
String name;

public Integer getProject_id() {
    return project_id;
}

public void setProject_id(Integer project_id) {
    this.project_id = project_id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

String description;
}

疑问:这是否是保留字相关问题?


问题原因与解决方案

这不是Postgres保留字问题,根源是Spring Data JPA的属性命名解析规则:
Spring Data JPA在解析排序参数时,会把下划线_当作驼峰命名的分隔符,将project_id拆分为project和id,尝试查找Project类中名为project的属性,显然不存在,因此抛出PropertyReferenceException。

解决方法1:遵循Java驼峰命名规范(推荐)

修改实体类的字段名和对应的getter/setter为Java驼峰格式,通过@Column注解映射到数据库的下划线字段:

@Entity
@Table(name = "Projects")
public class Project {
    @Id
    @GeneratedValue(generator = "ProjectSeq")
    @SequenceGenerator(name = "ProjectSeq", sequenceName = "PROJECTS_PROJECT_ID_SEQ", allocationSize = 1)
    @Column(name = "project_id") // 映射数据库字段
    Integer projectId; // 驼峰命名字段
    String name;
    String description;

    // 对应的驼峰格式getter/setter
    public Integer getProjectId() {
        return projectId;
    }

    public void setProjectId(Integer projectId) {
        this.projectId = projectId;
    }

    // 其他getter/setter保持不变...
}

然后修改排序代码,使用驼峰格式的属性名:

Sort sort = Sort.by("projectId").ascending();

解决方法2:直接指定数据库列名(无需修改实体类)

如果不想修改实体类的命名,可以使用JpaSort.unsafe()方法绕过Spring Data JPA的属性解析,直接指定数据库的列名:

Sort sort = JpaSort.unsafe("project_id").ascending();

这种方式会直接将排序字段作为数据库列名传入SQL,避免属性解析错误。


内容的提问来源于stack exchange,提问作者Black

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 04:46:26