web-dev-qa-db-fra.com

org.postgresql.util.PSQLException: ERROR: la colonne user0_.id n'existe pas - Hibernate

J'ai une classe de modèle mappée sur une base de données postgres à l'aide de hibernate. Ma classe de modèle est:

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

J'essaie de récupérer l'utilisateur avec le nom d'utilisateur "adam" en utilisant la requête ci-dessous:

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

Je reçois une exception qui dit:

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

Ma base de données de bash Shell ressemble à ceci:

database

Comment hibernate mappe-t-il les attributs de classe aux colonnes de table? Correspond-il uniquement en fonction de la fonction @Column(name="username") ou tente-t-il également de le faire en fonction de types de données et de contraintes telles que l'incrémentation unique/automatique?

21
swdon

Solution

Dans PostgreSQL vous devez spécifier le nom du schéma de la manière suivante:

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

Longue histoire

vous avez cette erreur:

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

parce que lorsque vous créez une base de données dans PostgreSQL , il crée un schéma par défaut nommé public , donc si vous ne spécifiez pas le nom dans le Entity, Hibernate vérifiera automatiquement le schéma public .


Bonnes pratiques

  1. N'utilisez pas les lettres majuscules dans le nom de database, schema, tables ou columns dans PostgreSQL . Sinon, vous devriez échapper ces noms avec des guillemets, ce qui peut provoquer des erreurs de syntaxe. Vous pouvez donc utiliser:
@Table(name="table_name", schema = "schame_name")
             ^^^^^^^^^^             ^^^^^^^^^^^
  1. le mot clé [~ # ~] utilisateur [~ # ~] est un mot clé réservé en PostgreSQL jetez un oeil à
+----------+-----------+----------+-----------+---------+
| Key Word |PostgreSQL |SQL:2003  | SQL:1999  | SQL-92  |
+----------+-----------+----------+-----------+---------+
|  ....        ....       ....       ....       ....    |
+----------+-----------+----------+-----------+---------+
| USER     |  reserved |reserved  | reserved  | reserved|
+----------+-----------+----------+-----------+---------+
  1. à la différence entre Dto et Entity sa bonne pratique d’utiliser Entity dans le fin du nom de votre entité, par exemple UserEntity
32
YCF_L

Pour les personnes obtenant cette exception, dans postgres, chaque fois que vous écrivez une classe d'entité, essayez de l'associer au bon schéma (où votre table est présente), comme ceci:

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

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

   // Other data
}

Comme @YCF_L a dit n'utilisez pas de lettres majuscules dans un nom de table ou de colonne, sinon vous obtiendrez cette exception.

Cette convention devient plus importante quand il s’agit d’un scénario dans lequel vous devez générer automatiquement les tables des classes d’entités ou inversement.

0
Vikash Kumar