Erreur de validation: la valeur n’est pas valide

J’ai un problème avec ap: selectOneMenu, peu importe ce que je fais, je ne peux pas demander à JSF d’appeler le setter sur l’entité JPA. La validation JSF échoue avec ce message:

form: location: Erreur de validation: la valeur n’est pas valide

Je travaille sur plusieurs autres classes du même type (c.-à-d. Joindre des classes de tables) mais je ne peux pas, pour la vie de moi, faire fonctionner celle-ci.

Si quelqu’un pouvait donner des conseils de dépannage ou de débogage pour ce type de problème, cela serait grandement apprécié.

Utilisation des instructions de journal J’ai vérifié les éléments suivants:

  1. Le Conveter renvoie des valeurs correctes et non null .
  2. Je n’ai pas de validation Bean dans mes entités JPA.
  3. Le setter setLocation(Location location) n’est jamais appelé.

C’est l’exemple le plus simple que je puisse faire et ça ne fonctionnera tout simplement pas:

   

Convertisseur:

 @FacesConverter(forClass=Location.class, value="locationConverter") public class LocationConverter implements Converter, Serializable { private static final Logger logger = Logger.getLogger(LocationConverter.class.getName()); @Override public Object getAsObject(FacesContext context, UIComponent component, Ssortingng value) { if (value.isEmpty()) return null; try { Long id = Long.parseLong(value); Location location = ((LocationManagedBean) context.getApplication().getELResolver().getValue(context.getELContext(), null, "location")).find(id); logger.log(Level.SEVERE, "Converted {0} to {1}" , new Object[] {value, location}); return location; } catch (NumberFormatException e) { return new Location(); } } @Override public Ssortingng getAsSsortingng(FacesContext context, UIComponent component, Object value) { if (value == null || value.toSsortingng().isEmpty() || !(value instanceof Location)) return ""; return Ssortingng.valueOf(((Location) value).getId()); } } 

Sortie de la console:

 // Getter method INFO: Current value=ejb.locations.Location[id=null, name=null, latitude=0.0, longitude=0.0] // Session Bean INFO: Finding ejb.locations.Location with id=3 // Session Bean INFO: ### Returning : ejb.locations.Location[id=3, name=mdmd, latitude=4.5, longitude=2.3] // Converter SEVERE: Converted 3 to ejb.locations.Location[id=3, name=mdmd, latitude=4.5, longitude=2.3] // Getter method -> Where did my selected Location go ?? INFO: Current value=ejb.locations.Location[id=null, name=null, latitude=0.0, longitude=0.0] 

La validation échoue avec le message “form: location: Erreur de validation: la valeur n’est pas valide”

Cette erreur se résume à ce que l’élément sélectionné ne correspond à aucune des valeurs d’élément de sélection disponibles spécifiées par une nestede lors du traitement de la demande de soumission de formulaire.

Dans le cadre de la protection contre les requêtes altérées / piratées, JSF réitérera toutes les valeurs d’éléments de sélection disponibles et testera si selectedItem.equals(availableItem) renvoie true pour au moins une valeur d’article disponible. Si aucune valeur ne correspond à un élément, vous obtenez exactement cette erreur de validation.

Ce processus se trouve essentiellement sous les couvertures ci-dessous, où bean.getAvailableItems() représente la liste complète des éléments de sélection disponibles définis par :

 Ssortingng submittedValue = request.getParameter(component.getClientId()); Converter converter = component.getConverter(); Object selectedItem = (converter != null) ? converter.getAsObject(context, component, submittedValue) : submittedValue; boolean valid = false; for (Object availableItem : bean.getAvailableItems()) { if (selectedItem.equals(availableItem)) { valid = true; break; } } if (!valid) { throw new ValidatorException("Validation Error: Value is not valid"); } 

Donc, sur la base de la logique ci-dessus, ce problème peut logiquement avoir au moins les causes suivantes:

  1. L’élément sélectionné est manquant dans la liste des éléments disponibles.
  2. La méthode equals() de la classe représentant l’élément sélectionné est manquante ou cassée.
  3. Si un Converter personnalisé est impliqué, alors il a renvoyé le mauvais object dans getAsObject() . C’est peut-être même null .

Pour le résoudre:

  1. Assurez-vous que la même liste est conservée lors de la requête suivante, notamment en cas de plusieurs menus en cascade. Faire le bean @ViewScoped au lieu de @RequestScoped devrait le réparer dans la plupart des cas. Veillez également à ne pas exécuter la logique métier dans la méthode getter de , mais plutôt dans la @PostConstruct ou une méthode d’événement d’action (écouteur). Si vous comptez sur des parameters de requête spécifiques, vous devrez les stocker explicitement dans le bean @ViewScoped ou les @ViewScoped sur les requêtes suivantes, par exemple . Voir aussi Comment choisir la bonne étendue de haricot?
  2. Assurez-vous que la méthode equals() est correctement implémentée. Ceci est déjà fait correctement sur les types Java standard tels que java.lang.Ssortingng , java.lang.Number , etc., mais pas nécessairement sur les objects / beans / entites personnalisés. Voir aussi Comment mettre en œuvre un contrat égal . Si vous utilisez déjà Ssortingng , assurez-vous que le codage des caractères de la requête est correctement configuré. S’il contient des caractères spéciaux et que JSF est configuré pour rendre la sortie en UTF-8 mais interprète l’entrée comme par exemple ISO-8859-1, alors il échouera. Voir aussi: Une entrée Unicode récupérée via les composants d’entrée PrimeFaces est corrompue .
  3. Déboguer / enregistrer les actions de votre Converter personnalisé et le corriger en conséquence. Pour plus d’informations, reportez-vous également à la section Définition de l’erreur de conversion pour ‘null Converter’ Dans le cas où vous utilisez java.util.Date comme élément disponible avec , veillez à ne pas oublier la partie temps du modèle. . Voir aussi “Erreur de validation: la valeur n’est pas valide” erreur de f: datetimeConverter .

Voir également:

  • Notre page wiki selectOneMenu
  • Comment remplir les options de h: selectOneMenu from database?
  • Rendre plusieurs listes déroulantes selectOneMenu dépendantes / en cascade dans JSF

Si quelqu’un pouvait donner des conseils de dépannage ou de débogage pour ce type de problème, cela serait grandement apprécié.

Posez simplement une question claire et concrète ici. Ne posez pas de questions trop larges;)

Dans mon cas, j’ai oublié d’implémenter une méthode get / set correcte. C’est arrivé parce que j’ai changé beaucoup d’atsortingbuts tout au long du développement.

Sans une méthode get appropriée, JSF ne peut pas récupérer l’élément sélectionné, et il arrive ce que BalusC a dit au point 1 de sa réponse:

1 . L’élément sélectionné est manquant dans la liste des éléments disponibles. Cela peut se produire si la liste des éléments disponibles est servie par un bean de requête dont la requête n’est pas correctement réinitialisée ou qui effectue incorrectement le travail métier dans une méthode getter, ce qui provoque le renvoi d’une liste différente.

Cela peut être un problème de convertisseur ou un problème de DTO. Essayez de résoudre ce problème en ajoutant les méthodes hashCode () et equals () dans votre object DTO; Dans le scénario ci-dessus, vous pouvez générer ces méthodes dans la classe d’object Location qui indique ici le «DTO».

Exemple:

 @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) (id ^ (id >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Location other = (Location) obj; if (id != other.id) return false; return true; } 
  • Veuillez noter que l’exemple ci-dessus concerne un “identifiant” de type “long”.