簡體   English   中英

org.postgresql.util.PSQLException:錯誤:列 user0_.id 不存在 - Hibernate

[英]org.postgresql.util.PSQLException: ERROR: column user0_.id does not exist - Hibernate

我有一個 model class 使用 hibernate 映射到 postgres 數據庫。我的 model class 是:

@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 map class 是如何歸屬於表列的? 它是僅基於@Column(name="username")進行匹配,還是也嘗試基於數據類型和約束(例如唯一/自動遞增)進行匹配?

解決方案

PostgreSQL 中,您必須像這樣指定模式的名稱:

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

長篇大論

你有這個錯誤:

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

因為當您在PostgreSQL 中創建數據庫時,它會創建一個名為public的默認架構,所以當您沒有在Entity指定名稱時,Hibernate 將自動檢查公共架構。


良好做法

  1. 不要在PostgreSQL 中databaseschematablescolumns的名稱中使用大寫字母。 否則你應該用引號轉義這個名字,這會導致語法錯誤,所以你可以使用:

@Table(name="table_name", schema = "schame_name")
             ^^^^^^^^^^             ^^^^^^^^^^^
  1. 關鍵字USERPostgreSQL 中的保留關鍵字看看

+----------+-----------+----------+-----------+---------+
| Key Word |PostgreSQL |SQL:2003  | SQL:1999  | SQL-92  |
+----------+-----------+----------+-----------+---------+
|  ....        ....       ....       ....       ....    |
+----------+-----------+----------+-----------+---------+
| USER     |  reserved |reserved  | reserved  | reserved|
+----------+-----------+----------+-----------+---------+
  1. 為了區分DtoEntity在實體名稱的末尾使用 Entity 的良好做法,例如UserEntity

對於遇到此異常的人,在 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 所說,不要在表名或列名中使用大寫字母,否則您將收到此異常。

當您必須從實體類自動生成表或反之亦然的情況下,此約定變得更加重要。

應該在實體類上添加模式名稱。 對於此示例,當架構名稱為 public 時

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

請參閱下面的 PostgreSQL 管理員視圖

在此處輸入圖片說明

有關 SpringBoot Java 和 Postgre SQL 連接的更多信息,請參見此處: https ://cmsoftwaretech.wordpress.com/2020/04/25/springboot-thymleaf-using-postgresql/

我使用通用名稱獲得,例如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以解決此問題。

Schema 仍然是public

由於mycoolappuser或后綴一些名稱,如mycoolappuserusermycoolapp以避免出現這樣的麻煩。

在下面找到一個包含禁止用作表、列和進一步自定義名稱的保留關鍵字和文字的列表。

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

在這種情況下, user被保留用於PostgreSQLSQL:2003SQL:1999SQL-92

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

在您的 POJO 類 Id 字段中。 這件事解決了我的錯誤。

嘗試從 pg 管理控制台drop table schema_name.table_namedrop table schema_name.table_name )並確保您的實體類正確注釋。例如實體類上的@Table(name = "table_name", schema = "schema_name")

除了之前所有的正確答案之外,我想說 @Column 和 @GeneratedValue 注釋的定位也很重要。 您希望在特定字段或 getter 方法上方同時擁有這兩個注釋,但不能分開(不是一個注釋位於 getter 上方,另一個注釋位於字段上方)。 至少對我有用。

我通過將列名從nameLikeThis更改為name_like_this來解決這個問題

ALTER TABLE table RENAME nameLikeThis to name_like_this;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM