org.postgresql.util.PSQLException:错误:列 user0_.id 不存在 - 休眠

Posted

技术标签:

【中文标题】org.postgresql.util.PSQLException:错误:列 user0_.id 不存在 - 休眠【英文标题】:org.postgresql.util.PSQLException: ERROR: column user0_.id does not exist - Hibernate 【发布时间】:2018-01-28 15:44:36 【问题描述】:

我有一个使用 hibernate 映射到 postgres 数据库的模型类。我的模型类是:

@Entity
@Table(name="USER")
public class User 

    @Id 
    @GeneratedValue
    @Column(name="id")
    private long id;

    @Column(name="username", unique=true)
    private String username;

    @Column(name="email")
    private String email;

    @Column(name="created")
    private Timestamp created;

    public User(long id, String username, String email) 
        this.id = id;
        this.username = username;
        this.email = email;
    

我尝试使用以下查询检索用户名为“adam”的用户:

tx = session.beginTransaction();
TypedQuery<User> query = session.createQuery("FROM User u WHERE u.username = :username", User.class).setParameter("username", "adam");
user = query.getSingleResult();

我得到一个例外:

org.postgresql.util.PSQLException: ERROR: column user0_.id does not exist

我的 bash shell 数据库如下所示:

hibernate 如何将类属性映射到表列?它是仅基于@Column(name="username") 匹配,还是也尝试基于数据类型和约束(例如唯一/自动增量)进行匹配?

【问题讨论】:

您使用的 shcema 的名称是什么? 架构名称是myapp 【参考方案1】:

##解决方案

PostgreSQL 中,您必须像这样指定架构的名称:

@Table(name="table_name", schema = "myapp")
                          ^^^^^^^^^^^^^^^^

##长篇大论

你遇到了这个错误:

org.postgresql.util.PSQLException: ERROR: column user0_.id does not exist

因为当你在 PostgreSQL 中创建数据库时,它会创建一个名为 public 的默认架构,所以当你没有在 Entity 中指定名称时,然后 Hibernate将自动检查 public 架构。


##良好做法

    不要在 PostgreSQL 中在 databaseschematablescolumns 的名称中使用大写字母。否则,您应该使用引号转义此名称,这可能会导致语法错误,因此您可以使用:

@Table(name="table_name", schema = "schema_name")
             ^^^^^^^^^^             ^^^^^^^^^^^
    关键字USERPostgreSQL中的保留关键字take a look at

+----------+-----------+----------+-----------+---------+
| Key Word |PostgreSQL |SQL:2003  | SQL:1999  | SQL-92  |
+----------+-----------+----------+-----------+---------+
|  ....        ....       ....       ....       ....    |
+----------+-----------+----------+-----------+---------+
| USER     |  reserved |reserved  | reserved  | reserved|
+----------+-----------+----------+-----------+---------+
    DtoEntity 之间的区别最好在实体名称末尾使用实体,例如 UserEntity

【讨论】:

感谢您更新答案。我无法放置实际架构,因为它包含一些业务信息。但是你的建议解决了这个问题:) 没问题@swdon你想要另一个解决方案还是什么? 不,我按照你原来的答案,现在没有问题。一切都按预期工作。我们可以关闭线程。非常感谢您的帮助! 谢谢兄弟,在列名中使用大写字母是我的问题 我每次都喜欢这个鬼鬼祟祟的 USER 关键字?【参考方案2】:

除了前面所有的正确答案,我想说的是@Column和@GeneratedValue注解的定位也很重要。您希望将这两个注释都放在特定字段或 getter 方法之上,但不能分开(不是一个注释在 getter 之上,另一个在字段之上)。至少对我有用。

【讨论】:

【参考方案3】:

尝试从 pg 管理控制台 (drop table schema_name.table_name) 删除表并确保您的实体类已正确注释。例如实体类上的 @Table(name = "table_name", schema = "schema_name")

【讨论】:

【参考方案4】:

我使用user 之类的通用名称在应用程序中制造了麻烦。

我遇到了与此处报告的相同问题,使用以下简单实体。

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;

@Entity
public class User implements Serializable 

    private static final long serialVersionUID = 6843302791607583447L;

    @Id
    @SequenceGenerator(name = "user_id_seq", sequenceName = "user_id_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_seq")
    private Long id;

    @Column
    private String name;

    @Column
    private String password;

    @Override
    public String toString() 
        return name;
    

    public Long getId() 
        return id;
    

    public String getName() 
        return name;
    

    public void setName(final String name) 
        this.name = name;
    

    public String getPassword() 
        return password;
    

    public void setPassword(final String password) 
        this.password = password;
    


我所做的只是将实体从 User 重命名为 Sessionxuser(并将数据表从 user 重命名为 sessionxuser 以解决此问题。

架构仍然是 public

由于前缀或后缀一些名称,如 mycoolappuserusermycoolapp,以避免此类麻烦。

在下面查找包含保留关键字和文字的列表,以防止用作表、列和进一步自定义的名称。

https://www.postgresql.org/docs/8.1/sql-keywords-appendix.html

在这种情况下,userPostgreSQLSQL:2003SQL:1999SQL-92 保留。

【讨论】:

【参考方案5】:

应在 Entity 类上添加模式名称。 对于此示例,当架构名称为 public 时

@Table(name = "user", schema = "public")

查看下面的 PostgreSQL 管理视图

有关 SpringBoot Java 和 Postgre SQL 连接的更多信息,请参见此处: https://cmsoftwaretech.wordpress.com/2020/04/25/springboot-thymleaf-using-postgresql/

【讨论】:

【参考方案6】:

使用:@GeneratedValue(strategy = GenerationType.IDENTITY)

在您的 POJO 类 Id 字段中。这件事解决了我的错误。

【讨论】:

【参考方案7】:

对于遇到此异常的人,在 postgres 中,每当您编写实体类时,请尝试将其与正确的架构(您的表所在的位置)相关联,如下所示:

@Entity
@Table(name = "user", schema = "users_details")
public class User implements Serializable

    @Column(name = "id")
    Long id;    //long is not recommended

   // Other data

正如@YCF_L 所说,不要在表名或列名中使用大写字母,否则你会得到这个异常。

当您必须从实体类自动生成表或反之亦然的情况下,此约定变得更加重要。

【讨论】:

以上是关于org.postgresql.util.PSQLException:错误:列 user0_.id 不存在 - 休眠的主要内容,如果未能解决你的问题,请参考以下文章