PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Java Enums, JPA et Postgres enums - Comment puis-je les faire fonctionner ensemble ?

J'ai en fait utilisé un moyen plus simple que celui avec PGObject et Converters. Étant donné que dans Postgres, les énumérations sont converties assez naturellement en texte, il vous suffit de le laisser faire ce qu'il fait le mieux. Je vais emprunter l'exemple d'humeur d'Arjan, s'il n'y voit pas d'inconvénient :

Le type d'énumération dans Postgres :

CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');

La classe et l'énumération en Java :

public @Entity class Person {

  public static enum Mood {sad, ok, happy};

  @Enumerated(EnumType.STRING)
  Mood mood;

}

Cette balise @Enumerated indique que la sérialisation/désérialisation de l'énumération doit être effectuée dans le texte. Sans cela, il utilise int, ce qui est plus gênant qu'autre chose.

À ce stade, vous avez deux options. Soit :

  1. Ajouter stringtype=unspecified à la chaîne de connexion, comme expliqué dans les paramètres de connexion JDBC. Cela permet à Postgres de deviner le type de droite et de tout convertir de manière adéquate, puisqu'il reçoit quelque chose comme 'enum =unknown', qui est une expression dont il sait déjà quoi faire (feed la valeur ? au désérialiseur de type gauche). C'est l'option préférée, car cela devrait fonctionner pour tous les UDT simples tels que les énumérations en une seule fois.

    jdbc:postgresql://localhost:5432/dbname?stringtype=unspecified
    

Ou :

  1. Créez une conversion implicite de varchar en enum dans la base de données. Ainsi, dans ce deuxième cas, la base de données reçoit une affectation ou une comparaison telle que 'enum =varchar' et trouve une règle dans son catalogue interne indiquant qu'elle peut transmettre la valeur de droite via la fonction de sérialisation de varchar suivie de la fonction de désérialisation du énumération. C'est plus d'étapes que nécessaire ; et avoir trop de transtypages implicites dans le catalogue peut entraîner des interprétations ambiguës des requêtes arbitraires, alors utilisez-le avec parcimonie. La création du casting est :

    CREATE CAST (PERSONNAGE VARIANT selon l'humeur) AVEC INOUT COMME IMPLICITE ;

Ça devrait marcher avec ça.