6
votes

Hibernate / JPA Bug - ne reconnaissant pas certaines chaînes dans une énorme

J'ai une énumération dans une classe, cartographiée par hibernate. L'un des champs mappés est et un type d'enum qui possède l'une des valeurs suivantes OK forte>, NOK forte> ou sieste forte>. NOK STRAND> ou NAP STROND> fonctionne comme prévu, mais lorsque le champ est défini sur "OK", Hibernate échoue à mapper et récupérer la valeur, qui est défini sur NULL: xxx pré>

la classe a: p> xxx pré>

si je change ok fort> à ok2 fort>, Cela fonctionne correctement. _OK strong> fonctionne aussi. En ce qui me concerne "OK" n'est pas un nom réservé (comme dans ce cas où le gars Utilise nouveau strud> ) car il compile correctement. p>

merci! p>

update: strong> p>

up jusqu'à maintenant, ce que j'ai fait pour résoudre le problème, c'est modifier l'ENUM et Stockez ' _ok fort>' dans la base de données au lieu de ' ok fort>', comme indiqué ci-dessus. Pas très belle solution, mais cela fonctionne au moins. P>

public enum Status {
    _OK("OK"), 
    NOK("NOK"), 
    NAP("NAP");

    private String desc;

    private Status(String desc){
        this.desc = desc;
    }

    public String getDesc(){
        return desc;
    }
}


5 commentaires

Vos différents tests semblent bien pensés. Il semble que vous avez un bug! Veuillez signaler via Jira de Hibernate, y compris votre exemple de code.


Je viens de répondre à une question similaire Stackoverflow.com/Questions/ 6419783 / Enum-Mapping-in-hibernat E / ...


@telm, j'utilise hibernate 3.4.0.ga et cela pourrait être le problème. Mais, je dois être prudent si je veux passer à 3.5.6 ou (3.6.5, la dernière finale) car c'est défini sur un Maven Pom.xml utilisé dans de nombreux produits. Donc, je devrais courir des tests avant cela. Mais merci pour le conseil. Je pourrais faire comme @bohemian raconté et remplir une demande de bug.


FWIW J'ai essayé votre exemple avec Datanuctue JPA, les objets ont persisté bien avec toutes les valeurs et toutes relues dans OK.


@telm, @Datanuctue, même problème avec 3.6.5.finale. Je pense que le problème est dans l'hibernate-annotations qui n'a pas changé de 3.4.0.ga lorsque j'ai changé la version hibernate sur le pom.xml. Je vais essayer cela avant de signaler.


3 Réponses :


10
votes

Le problème que vous avez est que, dans votre base de données, vous avez des valeurs autres que OK, NOK, NAP et lorsque vous récupérez les enregistrements, c'est lorsque vous obtenez l'exception, pas lorsque vous persistez.

à partir de votre exception com.abcdclass $ Statut: OK2 Il semble que votre base de données a cette valeur et donc le java.lang.illegalargumentException: valeur de nom inconnu pour la classe Enum Exception.

Vérifiez votre table pour des valeurs non valides, supprimez-les / corrigez-les et réessayez.


7 commentaires

La base de données a la valeur OK2 car j'ai changé d'ok pour tester la valeur OK2 dans l'ENUM.


Oui et c'est pourquoi il échoue lorsque vous le modifiez correctement, car les valeurs ENUM ne correspondent pas aux valeurs de propriété. C'est exactement ce que votre exception souligne. Si vous corrigez les valeurs et obtenez une autre exception s'il vous plaît faites le moi savoir.


Pour remédier à tous les tests, j'ai défini le record que je vis de «ok» et tout le reste est toujours null . En outre, l'Enum contient «OK», «NOK» et «NAP». Je reçois l'exception suivante: java.lang.illegalargumentException: nom de nom inconnu pour Enum classe com.abcdclass $ Statut: OK à org.hibernate.type.enumtype.nullsafeget (Enumtype.java:113) J'ai également essayé de définir tous les enregistrements de la base de données dans la table sur Statut ** = 'OK', donc aucun enregistrement n'a ** Statut ** = _ null_ nulmore, mais j'ai eu ** la même exception comme ci-dessus.


Pourquoi utilisez-vous @joincolumn au lieu de @column ?


Eh bien, probablement une erreur. Corrigé cela, mais les problèmes persistent. Avez-vous vu la solution mise à jour, qui est une solution rapide mais pas si agréable? Autre que cela me fait croire que c'est un bug.


@Lucasarruda Vous avez probablement raison, ce doit être un bug. Heureux de savoir que vous avez trouvé une solution acceptable.


Merci, @ Marcelo-Hernandez-Rishmawy. J'essaie avec une nouvelle version et je vais remplir un rapport de bogue.



2
votes

J'ai exactement le même problème après la mise à niveau de HSQLDB de 1,8 à 2.2.6. Pour Enums Hibernate crée des colonnes de caractère de type qui est une colonne de longueur fixe (contraire à Varchar). La longueur de celui-ci est probablement déterminée comme une longueur de la plus longue valeur enum. Les instructions d'insertion / mise à jour sont générées correctement par Hibernate, mais lors de la lecture des valeurs de la table, ces valeurs plus courtes sont annexées avec des espaces blancs.

Donc, il semble que le pilote HSQLDB ne les a pas coupés. Et si cela devrait, je pense que le bogue doit être déposé pour HSQLDB, pas d'hibernation. Toutefois, si ce comportement de HSQLDB est compatible avec SQL Standard, il est que l'enumtype de Hibernate devrait faire une coupe lorsque vous lisez des valeurs ENUM.


7 commentaires

Merci pour votre aperçu. J'ai rempli le bogue chez Hibernate's Jira dans l'espoir de clarifier ce que ce bug pourrait être. J'envisage de le remplir aussi sur le suivi de bugs HSQLDB, mais j'attendrais un changement de statut sur le premier, aller plus loin sur le sujet.


Dernière HSQLDB est compatible avec la norme SQL. Caractère (3) signifie que la chaîne est rembourrée avec des espaces si elle est plus courte. Plusieurs autres bases de données fonctionnent de la même manière.


Eh bien, alors n'est pas un bug, @fredt. Merci


@Lucasaruda, avez-vous utilisé Hibernate pour générer automatiquement le schéma de base de données? Je vous demande, puisque si cela est hiberné qui a généré la colonne d'un type de longueur fixe, alors hibernate devrait pouvoir lire à partir de cette colonne sans problème, sinon la logique de Hibernate se révélerait incompatible, donc contenant un bogue.


Non, il a été créé par le DBA. Autant que je me souvienne (parce que je ne travaille pas à la place, je l'ai fait ce code), le champ a été défini par Varcharate (3). Et cela pourrait être le problème. Mais si le champ où un varchar (x), avec x> 3, ne serait-il pas censé fonctionner aussi?


En cas de varchar (3) , il doit fonctionner parfaitement dans votre cas (car la longueur de champ est variable et que les valeurs d'état d'état ne sont supérieures à 3 caractères), bien que caractère (3) < / Code> vous donne des valeurs ajoutées avec des espaces blancs pour les valeurs plus courtes de 3 caractères, c'est-à-dire "ok" . Donc, le bug déposé dans Hibernate Jira semble être inapproprié. (Cependant, je pense toujours que Hibernate devrait être suffisamment intelligent pour traiter des colonnes de longueur fixe dans de tels cas. Partira pour la contrepartie de Devs Hibernate.)


Je l'obtiens, mais je pense toujours que le Char (3) ressemble plus à un piratage, car vous pouviez en réalité avoir un, B, C, K, OK comme un énumble, ce qui signifie que nous avons en réalité CHAR (2). Quoi qu'il en soit, Hibernate devrait couvrir le cas lorsque vous ne spécifiez pas le nombre de caractères, car cela fonctionne pour Char> 2 et il devrait fonctionner pour char <= 1.



3
votes

Comme une autre solution de contournement, vous pouvez essayer de fournir une définition de colonne exacte pour avoir une colonne VARCHAR:

@Column(columnDefinition = "VARCHAR(3)")
// @Column(columnDefinition = "VARCHAR2(3)") // VARCHAR2 for Oracle
@Enumerated(EnumType.STRING)
public Status getStatus() {
    return status;
}

public enum Status {
    OK, NOK, NAP;
}


0 commentaires