Validation 验证错误:值无效

Validation 验证错误:值无效,validation,jsf,jpa,converter,selectonemenu,Validation,Jsf,Jpa,Converter,Selectonemenu,我对p:selectOneMenu有一个问题,无论我做什么,我都无法让JSF调用JPA实体上的setter。JSF验证失败,并显示以下消息: 表单:位置:验证错误:值无效 我在其他几个相同类型的类(例如,jointtable类)上也有这样的工作,但我一辈子都不能让这个工作 如果有人能为此类问题提供一些故障排除/调试技巧,我们将不胜感激 我使用日志语句验证了以下内容: converter正在返回正确的非null值 我的JPA实体中没有Bean验证 永远不会调用settersetLocation(L

我对p:selectOneMenu有一个问题,无论我做什么,我都无法让JSF调用JPA实体上的setter。JSF验证失败,并显示以下消息:

表单:位置:验证错误:值无效

我在其他几个相同类型的类(例如,jointtable类)上也有这样的工作,但我一辈子都不能让这个工作

如果有人能为此类问题提供一些故障排除/调试技巧,我们将不胜感激

我使用日志语句验证了以下内容:

  • converter
    正在返回正确的非
    null
  • 我的JPA实体中没有Bean验证
  • 永远不会调用setter
    setLocation(Location-Location)
  • 这是我能做的最简单的例子,但它根本不起作用:

    <h:body>
        <h:form id="form">
            <p:messages id="messages" autoUpdate="true" />
            <p:selectOneMenu id="location" value="#{locationStockList.selected.location}" converter="locationConverter">
                <p:ajax event="change" update=":form:lblLocation"/>
                <f:selectItems value="#{locationStockList.locationSelection}"/>
            </p:selectOneMenu>
        </h:form>
    </h:body>
    
    控制台输出:

    // 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] 
    
    验证失败,消息为“表单:位置:验证错误:值无效”

    此错误归结为,在处理表单提交请求期间,所选项目与任何嵌套的
    标记指定的任何可用选择项目值都不匹配

    作为防止篡改/黑客请求的一部分,JSF将对所有可用的选择项值进行重申,并测试至少一个可用项值的
    selectedItem.equals(availableItem)
    是否返回
    true
    。如果没有一个项值匹配,那么您将得到这个验证错误

    这个过程基本上如下所示,其中
    bean.getAvailableItems()
    虚构地表示由
    定义的可用选择项的整个列表:

    因此,基于上述逻辑,该问题在逻辑上至少有以下原因:

  • 可用项列表中缺少选定项
  • 表示所选项的类的
    equals()
    方法缺失或已损坏
  • 如果涉及自定义的
    转换器
    ,则它在
    getaObject()
    中返回了错误的对象。甚至可能是
    null
  • 要解决这个问题:

  • 确保在后续请求期间保留完全相同的列表,特别是在多个级联菜单的情况下。在大多数情况下,使bean
    @ViewScoped
    而不是
    @requestscope
    应该可以修复它。还要确保您没有在
    的getter方法中执行业务逻辑,而是在
    @PostConstruct
    或操作事件(侦听器)方法中执行业务逻辑。如果您依赖于特定的请求参数,那么您需要将它们显式存储在
    @ViewScoped
    bean中,或者在后续请求中通过例如
    重新传递它们。另见
  • 确保正确实现了
    equals()
    方法。这已经在标准Java类型(如
    Java.lang.String
    Java.lang.Number
    )上正确地完成了,但不一定在自定义对象/bean/Entite上完成。另见。如果您已经在使用
    字符串
    ,请确保请求字符编码配置正确。如果它包含特殊字符,并且JSF被配置为将输出呈现为UTF-8,但将输入解释为例如ISO-8859-1,那么它将失败。另见a.o
  • 调试/记录自定义
    转换器的操作
    ,并相应地进行修复。有关指导原则,请参见在将
    java.util.Date
    用作
    的可用项时,确保不要忘记模式中的全职部分。另见
  • 另见:

    如果有人能为此类问题提供一些故障排除/调试技巧,我们将不胜感激

    请在这里提出一个明确而具体的问题。不要问太宽泛的问题;)

    验证失败,消息为“表单:位置:验证错误:值无效”

    此错误归结为,在处理表单提交请求期间,所选项目与任何嵌套的
    标记指定的任何可用选择项目值都不匹配

    作为防止篡改/黑客请求的一部分,JSF将对所有可用的选择项值进行重申,并测试至少一个可用项值的
    selectedItem.equals(availableItem)
    是否返回
    true
    。如果没有一个项值匹配,那么您将得到这个验证错误

    这个过程基本上如下所示,其中
    bean.getAvailableItems()
    虚构地表示由
    定义的可用选择项的整个列表:

    因此,基于上述逻辑,该问题在逻辑上至少有以下原因:

  • 可用项列表中缺少选定项
  • 表示所选项的类的
    equals()
    方法缺失或已损坏
  • 如果涉及自定义的
    转换器
    ,则它在
    getaObject()
    中返回了错误的对象。甚至可能是
    null
  • 要解决这个问题:

  • 确保在后续请求期间保留完全相同的列表,特别是在多个级联菜单的情况下。在大多数情况下,使bean
    @ViewScoped
    而不是
    @requestscope
    应该可以修复它。还要确保您没有在
    的getter方法中执行业务逻辑,而是在
    @PostConstruct
    或操作事件(侦听器)方法中执行业务逻辑。如果您依赖于特定的请求参数,那么您需要将它们显式存储在
    @ViewScoped
    bean中,或者在后续请求中通过例如
    重新传递它们。另见
  • 确保正确实现了
    equals()
    方法。在标准Java类型上,如
    Java.lang.String
    Java.la,这一点已经做到了
    
    // 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] 
    
    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");
    }
    
    @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;
    }