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

Hibernate映射PostgreSQL报错column checkres0_.id不存在问题排查

解决Hibernate映射PostgreSQL现有表时的列不存在错误

你遇到的org.postgresql.util.PSQLException: ERROR: column checkres0_.id does not exist错误,核心原因是PostgreSQL对带双引号的标识符区分大小写,而你的Hibernate配置和实体映射没有适配现有表的大小写敏感结构。

问题根源分析

  1. 你的数据库表和列是用双引号创建的("ID"、"check"、"checkers"),PostgreSQL中这种带双引号的标识符是严格区分大小写的;而Hibernate默认会把实体字段名转成小写形式(比如把ID转成id),导致查询时找不到对应的大写列。
  2. 你配置的EJB3NamingStrategy虽然不会修改属性名,但结合PostgreSQL方言,Hibernate依然会将标识符转成小写,无法匹配你现有表的大小写敏感列。
  3. 之前Hibernate自动创建表没问题,是因为它生成的是不带双引号的小写标识符(比如id、checkers),PostgreSQL会自动识别为小写,所以不会报错,但这和你现有的表结构完全不同。

解决方案

下面提供两种可行的解决方式,你可以根据自己的需求选择:

方案1:精确指定实体映射的大小写敏感标识符

直接在@Table和@Column注解中指定与数据库完全匹配的带双引号的名称(注意Java字符串中双引号需要转义):

package com.example.demo.model;
import javax.persistence.Id;
import javax.persistence.*;

@Entity
@Table(name="\"checkers\"", schema = "public") // 匹配数据库的"checkers"表
public class CheckRes {
    @Id
    @Column(name="\"ID\"") // 匹配数据库的"ID"主键列
    private long ID;

    @Column(name="\"check\"") // 匹配数据库的"check"列(check是PostgreSQL关键字,必须用双引号包裹)
    private String check;

    // 构造函数、getter、setter保持不变
    public CheckRes() { }
    public CheckRes(String check) { this.check = check; }
    public long getID() { return ID; }
    public void setID(long ID) { this.ID = ID; }
    public String getCheck() { return check; }
    public void setCheck(String check) { this.check = check; }
}

方案2:配置Hibernate全局适配大小写敏感标识符

如果不想逐个字段指定,可通过配置让Hibernate自动处理大小写敏感的标识符,同时彻底禁用DDL操作(避免Hibernate修改现有表):
修改application.properties:

# 使用Spring物理命名策略,保留实体字段的大小写
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
# 全局开启标识符引号,让Hibernate对所有表/列名添加双引号,匹配PostgreSQL的大小写敏感规则
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
# 指定PostgreSQL方言
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
# 禁用DDL操作,彻底阻止Hibernate创建/修改表结构
spring.jpa.hibernate.ddl-auto = none

关键注意事项

  • 一定要把ddl-auto从update改成none:update会让Hibernate尝试对比实体和表结构并更新,可能会对你的现有表造成意外修改,none才是完全使用现有表的正确配置。
  • check是PostgreSQL的关键字,所以你的数据库表中必须用双引号包裹这个列名,Hibernate映射时也必须对应处理,否则会触发语法错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 20:38:02