2009-04-23 7 views
0

En travaillant avec Hibernate Validator, j'ai remarqué que les annotations @NotEmpty et @NotNull produisent des messages en double dans le tableau InvalidValue renvoyé par getInvalidValues(...).Pourquoi Hibernate Validator @NotEmpty génère-t-il des messages en double?

Si je spécifie un message comme @NotEmpty(message = "My error message."), j'obtiendrai une valeur InvalidValue de "Mon message d'erreur". et un second de "peut ne pas être nul ou vide"

Si je n'inclue pas de message (par exemple @NotEmpty en lui-même), alors j'obtiens deux copies de InvalidValue avec un champ de message "may not be null or vide". Pourquoi le validateur Hibernate fait-il cela??

Ne devrais-je pas recevoir un message, soit la valeur que je remplace en utilisant le paramètre, soit le message par défaut, mais pas les deux ??


Pour plus de contexte:

J'étends ClassValidator<T> avec ma propre mise en œuvre ClassValidator<MyClass>. Je le fais pour ajouter quelques validations personnalisées qui ne peuvent pas être effectuées par annotation. J'ai besoin de voir la valeur d'exécution de plus d'une propriété de la classe afin de déterminer la validation.

Je reçois les validations lorsque j'appelle myClassValidator.getInvalidValues ​​(), que je remplace. Dans ma mise en œuvre de getInvalidValues(), j'appelle le super.getInvalidValues() pour créer la liste d'erreurs initiale, puis j'ajoute mes erreurs personnalisées à cette liste. Dans tous les cas, l'appel à super.getInvalidValues() contient les messages en double, l'un correspondant à la propriété de message transmise dans l'annotation, et l'autre à la valeur de stock du message d'annotation.


Répondre

1

Justin,

Je travaille avec Hibernate Validator pour les deux derniers mois. Bien que je n'ai pas rencontré le même problème que vous avez décrit, je n'ai pas non plus étendu ClassValidator. Pour la validation personnalisée, le Hibernate Reference Guide indique que l'écriture de contraintes personnalisées est la solution.

J'ai été capable d'utiliser les contraintes intégrées presque exclusivement sur mon projet actuel. Dans un cas, où j'avais besoin de faire des calculs très spécifiques sur un champ entier, j'ai écrit une contrainte personnalisée comme décrit dans le guide de référence; c'était une brise.

En parlant à votre problème, j'ai écrit une application de test simple comme une sorte de vérification de la santé mentale de ma part:

import org.hibernate.validator.*; 

public class HibernateValidatorTest { 
    @NotEmpty 
    @NotNull 
    private String validateMe; 

    public static void main (String[] args) { 
     ClassValidator<HibernateValidatorTest> validator = 
      new ClassValidator<HibernateValidatorTest>(HibernateValidatorTest.class); 

     InvalidValue[] inVals = 
      validator.getInvalidValues(new HibernateValidatorTest()); 

     for (InvalidValue inVal : inVals) { 
      System.out.println(inVal.getMessage()); 
     } 
    } 
} 

Avec les deux Hibernate contraintes sur le terrain validateMe, la sortie de la console est:

may not be null or empty 
may not be null 

La suppression de l'un ou l'autre a pour effet d'imprimer un seul message sur la console.

J'espère que c'est utile.

Brian T. Grant

+0

yyou serait bien sûr obtenir deux erreurs si vous faites les deux @NotNull et @NotEmpty, mais ce n'est pas ce que je fais.Je annote seulement avec la seule contrainte, par exemple: @NotNull (message = "foo"), et si elle est traitée via le validateur de classe étendu, je reçois deux messages: "foo" et "ne peut pas être nul" –

+0

Il est vrai qu'il est préférable d'utiliser une contrainte personnalisée, mais cela ne fonctionne pas si vous avez besoin de comparer la valeur d'exécution de plusieurs propriétés de la classe pour effectuer la validation. Les annotations ne peuvent pas faire une telle chose. Une option consiste à essayer des annotations de niveau classe, en supposant que vous pouvez remplacer le chemin de propriété pour pointer vers le champ que vous validez vraiment ... –

+0

Justin, Je dois avoir manqué l'importance d'inspecter les valeurs d'exécution de plusieurs champs. Une option pour traiter une telle situation peut être d'annoter une méthode sur votre classe qui valide ces champs. Si vous mettez @AssertTrue sur la méthode, alors vous pouvez faire toute votre comparaison/validation multi-champs dans cette méthode et renvoyer vrai/faux selon que ces champs sont valides. Je me rends compte que votre question/problème de base peut toujours être la sous-classe ClassValidator. Je suggère simplement que vous pourriez obtenir ce dont vous avez besoin sans devoir étendre ClassValidator. –

Questions connexes