org.postgresql.util.PSQLException: ERROR: column user0_.id does not exist - Hibernate
Asked Answered
P

9

47

I have a model class that is mapped to a postgres database using hibernate. My model class is:

@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;
    }
}

I try to retrieve the user with username "adam" using the below query:

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

I get an exception that says:

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

My database from bash shell looks like:

database

How does hibernate map class attributes to table columns? Does it match based on the @Column(name="username") only or does it also try to match based on datatypes and constraints such as unique/auto-increment?

Pistole answered 20/8, 2017 at 12:49 Comment(2)
what is the name of your shcema you are using?Sutter
schema name is myapp.Pistole
S
69

Solution

In PostgreSQL you have to specify the name of schema like so :

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

Long Story

you got this error :

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

because when you create a database in PostgreSQL, it create a default schema named public, so when you don't specify the name in the Entity then Hibernate will check automatically in the public schema.


Good practices

  1. Don't use Upper letters in the name of database, schema, tables or columns in PostgreSQL. Else you should to escape this names with quotes, and this can cause Syntax errors, so instead you can use :

@Table(name="table_name", schema = "schema_name")
             ^^^^^^^^^^             ^^^^^^^^^^^
  1. the keyword USER is reserved keyword in PostgreSQL take a look at

+----------+-----------+----------+-----------+---------+
| Key Word |PostgreSQL |SQL:2003  | SQL:1999  | SQL-92  |
+----------+-----------+----------+-----------+---------+
|  ....        ....       ....       ....       ....    |
+----------+-----------+----------+-----------+---------+
| USER     |  reserved |reserved  | reserved  | reserved|
+----------+-----------+----------+-----------+---------+
  1. to difference between Dto and Entity its good practice to use Entity in the end of the name of your Entity for example UserEntity
Sutter answered 20/8, 2017 at 12:55 Comment(6)
Thanks for updating the answer. I can't put the actual schema as it contains some business information. But your advice fixed the issue :)Pistole
No, I followed your original answer and now there is no issue. Everything is working as expected. We can close the thread. Thanks very much for your help!Pistole
Thanks bro, using capital letters in column name was my issueImpropriety
I'm falling for this sneaky USER keyword every time🤦Bathrobe
What seriously? I didn't know user was a reserved keyword. Like everyone names their tables "users"?Boyette
@OmGupta take a look here postgresql.org/docs/8.1/sql-keywords-appendix.htmlSutter
B
7

For people getting this exception ,In postgres Whenever you write an Entity Class try to associate it with the correct schema (where your table is present), like this:

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

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

   // Other data
}

As @YCF_L has said Don't use Upper_case letters in a table name or column name otherwise you will get this exception.

This convention becomes more important when their is a scenario where you have to auto generate the tables from entity classes or vice-versa.

Badmouth answered 5/8, 2019 at 9:47 Comment(0)
B
5

Should add schema name on the Entity class. For this example, when the schema name is public

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

See the PostgreSQL Admin view below

enter image description here

See here for more about SpringBoot Java and Postgre SQL connectivity: https://cmsoftwaretech.wordpress.com/2020/04/25/springboot-thymleaf-using-postgresql/

Berkowitz answered 25/4, 2020 at 1:58 Comment(2)
I did this, but still facing the issue: [select u1_0.id from public.user u1_0 where u1_0.email=? fetch first ? rows only] [ERROR: relation "public.user" does not existBoyette
The default value for schema param is 'public'Flats
H
2

I obtained using general names like user are making troubles in the app.

I got the same issue as reported here with the following simple entity.

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;
    }

}

All i did was renaming the entity from User to Sessionxuser (and renaming the datatable from user to sessionxuser to fix this issue.

Schema was still public.

Since pre- or postfix some names like mycoolappuser or usermycoolapp to avoid troubles like this.

Find below a list with reserved keywords and literals preventing using as table, column, and further customized names.

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

In this case user is preserved for PostgreSQL, SQL:2003, SQL:1999 and SQL-92.

Hercule answered 26/5, 2020 at 12:11 Comment(0)
W
2

Try Dropping the table from pg admin console (drop table schema_name.table_name)and make sure your entity class is proper annotated.For example @Table(name = "table_name", schema = "schema_name") on entity class

Wind answered 4/8, 2020 at 8:38 Comment(0)
T
2

Change

@Table(name="USER")

To

@Table(name"/"USER/"")

USER is a reserved word, so it needs the " character.

Tufted answered 20/11, 2023 at 12:21 Comment(0)
B
1

Use: @GeneratedValue(strategy = GenerationType.IDENTITY)

In your POJO class Id Field. This thing solved my error.

Bogeyman answered 26/12, 2019 at 11:39 Comment(0)
E
0

In addition to all previous correct answers, I'd like to say that the positioning of annotations @Column and @GeneratedValue also matters. You want to have both these annotations above either the specific field or getter method, but not separately (not one annotation above the getter and the other above the field). It worked for me at least.

Encamp answered 23/6, 2021 at 14:51 Comment(0)
E
0

I fixed the issue by altering the column name from nameLikeThis to name_like_this

ALTER TABLE table RENAME nameLikeThis to name_like_this;
Eyeopening answered 9/12, 2022 at 15:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.