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

时间:2017-08-20 12:49:24

标签: java postgresql hibernate

我有一个使用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数据库如下:

database

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

7 个答案:

答案 0 :(得分:25)

阐释

它给你这个错误:

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

因为当您创建数据库PostgreSQL时,它会创建一个名为public的默认架构,所以当您不在Entity中指定名称时,它将在公共架构中自动检查,因为你得到这个错误。

另一件事确认架构名称是正确的,错误说:

column user0_.id does not exist

而不是:

column myapp.user0_.id does not exist
-------^----^

确认查询使用的是public schema而不是真正的schema myapp

解决方案

要解决此问题,您必须指定架构的名称,如下所示:

@Table(name="USER", schema = "myapp")

建议

请勿在PostgreSQL中的表或列名称中使用大写字母。

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

用户名称是PostgreSQL中的保留关键字look at

答案 1 :(得分:1)

对于遇到此异常的人,在postgres中,每当您编写一个Entity Class时,都尝试将其与正确的架构(存在表的地方)相关联,如下所示:

@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所说,不要在表名或列名中使用大写字母,否则您将收到此异常。

当您必须从实体类中自动自动生成表时,反之亦然。

答案 2 :(得分:1)

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

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

请参见下面的PostgreSQL Admin视图

enter image description here

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

答案 3 :(得分:1)

我使用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:1999保留了SQL-92

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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