Validation Error: Value is not valid

后端 未结 3 805
轮回少年
轮回少年 2020-11-21 04:22

I have a problem with a p:selectOneMenu, no matter what I do I cannot get JSF to call the setter on the JPA entity. JSF validation fails with this message:

3条回答
  •  余生分开走
    2020-11-21 04:46

    Validation fails with the message "form:location: Validation Error: Value is not valid"

    This error boils down to that the selected item does not match any of the available select item values specified by any nested tag during processing of the form submit request.

    As part of safeguard against tampered/hacked requests, JSF will reiterate over all available select item values and test if selectedItem.equals(availableItem) returns true for at least one available item value. If no one item value matches, then you'll get exactly this validation error.

    This process is under the covers basically as below, whereby bean.getAvailableItems() fictionally represents the entire list of available select items as defined by :

    String 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");
    }
    

    So, based on the above logic, this problem can logically have at least the following causes:

    1. The selected item is missing in the list of available items.
    2. The equals() method of the class representing the selected item is missing or broken.
    3. If a custom Converter is involved, then it has returned the wrong object in getAsObject(). Perhaps it's even null.

    To solve it:

    1. Ensure that exactly the same list is been preserved during the subsequent request, particularly in case of multiple cascading menus. Making the bean @ViewScoped instead of @RequestScoped should fix it in most cases. Also make sure that you don't perform the business logic in the getter method of , but instead in @PostConstruct or an action event (listener) method. If you're relying on specific request parameters, then you'd need to explicitly store them in the @ViewScoped bean, or to re-pass them on subsequent requests by e.g. . See also How to choose the right bean scope?
    2. Ensure that the equals() method is implemented right. This is already done right on standard Java types such as java.lang.String, java.lang.Number, etc, but not necessarily on custom objects/beans/entites. See also Right way to implement equals contract. In case you're already using String, make sure that the request character encoding is configured right. If it contains special characters and JSF is configured to render the output as UTF-8 but interpret the input as e.g. ISO-8859-1, then it will fail. See also a.o. Unicode input retrieved via PrimeFaces input components become corrupted.
    3. Debug/log the actions of your custom Converter and fix it accordingly. For guidelines, see also Conversion Error setting value for 'null Converter' In case you're using java.util.Date as available items with , make sure that you don't forget the full time part in the pattern. See also "Validation Error: Value is not valid" error from f:datetimeConverter.

    See also:

    • Our selectOneMenu wiki page
    • How to populate options of h:selectOneMenu from database?
    • Make multiple dependent / cascading selectOneMenu dropdown lists in JSF

    If anyone can throw some troubleshooting/debugging tips for this sort of problem it would be greatly appreciated.

    Just ask a clear and concrete question here. Do not ask too broad questions ;)

提交回复
热议问题