Org.postgresql.util.PSQLException: ОШИБКА: column user0_.id не существует - 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 выглядит следующим образом:

database

Как hibernate сопоставляет атрибуты класса класса столбцам таблицы? Совместим ли он только с параметром @Column(name="username") или же он также пытается сопоставляться на основе типов данных и ограничений, таких как уникальный/автоматический инкремент?

Ответ 1

Решение

В PostgreSQL вы должны указать имя схемы следующим образом:

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

Длинная история

Вы получили эту ошибку:

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

потому что, когда вы создаете базу данных в PostgreSQL, она создает схему по умолчанию с именем public, поэтому, если вы не укажете имя в Entity, Hibernate проверит автоматически в общедоступной схеме.


Хорошие практики

  1. Не используйте заглавные буквы в имени database, schema, tables или columns в PostgreSQL. В противном случае вы должны экранировать эти имена в кавычках, и это может вызвать синтаксические ошибки, поэтому вместо этого вы можете использовать:

@Table(name="table_name", schema = "schame_name")
             ^^^^^^^^^^             ^^^^^^^^^^^
  1. ключевое слово ПОЛЬЗОВАТЕЛЬ является зарезервированным ключевым словом в PostgreSQL ,посмотрите на

+----------+-----------+----------+-----------+---------+
| Key Word |PostgreSQL |SQL:2003  | SQL:1999  | SQL-92  |
+----------+-----------+----------+-----------+---------+
|  ....        ....       ....       ....       ....    |
+----------+-----------+----------+-----------+---------+
| USER     |  reserved |reserved  | reserved  | reserved|
+----------+-----------+----------+-----------+---------+
  1. для различия между Dto и Entity рекомендуется использовать Entity в конце имени вашего Entity, например UserEntity

Ответ 2

Для людей, получающих это исключение, в 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 Не используйте заглавные буквы в имени таблицы или столбца, в противном случае вы получите это исключение.

Это соглашение становится более важным, когда это сценарий, в котором вам нужно автоматически генерировать таблицы из классов сущностей или наоборот.