Java Enums, JPA et Postgres enums - Comment puis-je les faire travailler ensemble?
Nous avons une postgres DB avec postgres des enums. Nous commençons à construire JPA dans notre application. Nous avons aussi Java énumérations qui reflètent les postgres des enums. Maintenant la grande question est de savoir comment obtenir JPA pour comprendre Java enums sur un côté et postgres enums sur l'autre? La Java côté devrait être assez facile, mais je ne suis pas sûr de la façon de faire de postgres côté.
- nous nous dirigeons maintenant notre système de JPA trop, mais nous avons java enums mappés à des colonnes varchar encore eu aucun problème avec Hibernate
Vous devez vous connecter pour publier un commentaire.
Cela implique de faire des correspondances multiples.
Tout d'abord, une Postgres enum est renvoyé par le pilote JDBC comme une instance de type PGObject. Le type de propriété de ce qui a le nom de votre postgres enum, et la valeur de la propriété à sa valeur. (L'ordinal n'est pas stocké cependant, techniquement, ce n'est pas un enum plus et même complètement inutile à cause de cela)
De toute façon, si vous avez une définition de ce genre dans Postgres:
Puis le resultset contient un PGObject de type "humeur" et "heureux" d'une colonne d'avoir ce type d'énumération et une ligne avec la valeur "heureux".
Prochaine chose à faire est d'écrire quelques intercepteur code qui se trouve entre l'endroit où JPA lit à partir de la crue resultset et définit la valeur de votre entité. E. g. supposons que vous avez eu l'entité suivante en Java:
Malheureusement, JPA n'est pas facile d'interception point où vous pouvez faire la conversion de PGObject à la Java enum Humeur. La plupart des APC, les vendeurs ont cependant certaines propriétaire de soutien pour cette. Hibernate, par exemple, la définition de type et d'annotations de Type pour ce (à partir de Hibernate-annotations.jar).
Ces vous permettent de fournir une instance de UserType (à partir de Hibernate-core.jar) qui effectue la conversion:
Ce n'est pas une complète solution de travail, mais juste un petit pointeur espérons-le, dans la bonne direction.
En fait, j'ai été en utilisant une méthode plus simple que celle avec PGObject et les Convertisseurs. Depuis dans Postgres les énumérations sont convertis tout à fait naturellement à partir du texte, vous avez juste besoin de le laisser faire ce qu'il fait de mieux. Je vais emprunter Arjan de l'exemple de la bonne humeur, s'il n'a pas l'esprit:
Le type enum dans Postgres:
La classe enum en Java:
}
Que @Énumérés tag dit que la sérialisation/désérialisation de l'enum doit être fait dans le texte. Sans cela, il utilise des int, ce qui est plus gênant qu'autre chose.
À ce stade, vous avez deux options. Vous pouvez soit:
Ajouter chaînetapez=non spécifié à la chaîne de connexion, comme expliqué dans Les paramètres de la connexion JDBC.Cela vous permet de Postgres deviner le côté droit type et de convertir tout de manière adéquate, puisqu'il reçoit quelque chose comme 'enum = inconnu", qui est une expression qu'il sait déjà de quoi faire avec (nourrir ? la valeur de la main gauche type deserialiser). C'est l'option préférée, comme il devrait fonctionner pour tous les simples Udt tels que les enums en une seule fois.
Ou:
Créer une conversion implicite de type varchar enum dans la base de données. Donc, dans ce second cas, la base de données reçoit une affectation ou de comparaison comme "enum = varchar" et il trouve une règle dans son catalogue interne en disant qu'il puisse passer à la droite de la valeur grâce à la fonction de sérialisation de type varchar, suivie par la désérialisation fonction de l'enum. C'est plus d'étapes que doit être nécessaire; et avoir trop de conversions implicites dans le catalogue peuvent causer des requêtes arbitraires d'avoir des interprétations ambiguës, afin de l'utiliser avec parcimonie. La fonte de la création est:
CRÉER CAST (CHARACTER VARYING que l'humeur) AVEC INOUT IMPLICITE;
Devrait travailler avec cela.
J'ai déposé un rapport de bug avec un patch inclus pour la mise en veille prolongée: HHH-5188
Le patch fonctionne pour moi de lire un PostgreSQL enum dans un enum de Java à l'aide de JPA.
J'ai trouvé la meilleure solution:
Maintenant, nous pouvons utiliser la
PostgreSQLEnumType
comme suit: