JSF转换器验证错误:该值对于SelectOneMenu UIComponent无效

JSF转换器验证错误:该值对于SelectOneMenu UIComponent无效,jsf,jpa,Jsf,Jpa,我在requestScope中使用managedBeanuserHome,其中实体“用户”将被持久化。 该用户具有以多个关系映射的leader列 @ManagedBean @RequestScoped public class UserHome { private User user = new User(); // Getters and Setters private List<SelectItem> selectItems = new Arra

我在requestScope中使用managedBeanuserHome,其中实体“用户”将被持久化。 该用户具有以多个关系映射的leader列

@ManagedBean
@RequestScoped
public class UserHome {
    private User user = new User();
        // Getters and Setters

    private List<SelectItem> selectItems = new ArrayList<SelectItem>();

    public UserHome() {
        for(User user: availableLeaders) {
            selectItems.add(new SelectItem(user.getName(), user));
        }
    }

    public void persis();
}
<h:selectOneMenu value="#{userHome.user.leader}" converter="userConverter">
    <f:selectItems value="#{userHome.selectItems}"/>
</h:selectOneMenu>
@FacesConverter(forClass = User.class, value="userConverter")
public class UserConverter implements Converter {

    private  Map<String, User> userValues = new HashMap<String, User>();

    public UserConverter() {
        init();
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component,
            String value) {
        return userValues.get(value);
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        System.out.println("RAJASEKARAN "+value);
        return ((User)value).getName();
    }

    public void init() {
        UserHome userHome = new UserHome();
        for(User user:userHome.availableLeaders()) {
            userValues.put(user.getName(), user);
        }
    }
}
我试图通过如下方式通过
h:selectOneMenu
了解这位领导者的价值

@ManagedBean
@RequestScoped
public class UserHome {
    private User user = new User();
        // Getters and Setters

    private List<SelectItem> selectItems = new ArrayList<SelectItem>();

    public UserHome() {
        for(User user: availableLeaders) {
            selectItems.add(new SelectItem(user.getName(), user));
        }
    }

    public void persis();
}
<h:selectOneMenu value="#{userHome.user.leader}" converter="userConverter">
    <f:selectItems value="#{userHome.selectItems}"/>
</h:selectOneMenu>
@FacesConverter(forClass = User.class, value="userConverter")
public class UserConverter implements Converter {

    private  Map<String, User> userValues = new HashMap<String, User>();

    public UserConverter() {
        init();
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component,
            String value) {
        return userValues.get(value);
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        System.out.println("RAJASEKARAN "+value);
        return ((User)value).getName();
    }

    public void init() {
        UserHome userHome = new UserHome();
        for(User user:userHome.availableLeaders()) {
            userValues.put(user.getName(), user);
        }
    }
}

我的转换器看起来像这样

@ManagedBean
@RequestScoped
public class UserHome {
    private User user = new User();
        // Getters and Setters

    private List<SelectItem> selectItems = new ArrayList<SelectItem>();

    public UserHome() {
        for(User user: availableLeaders) {
            selectItems.add(new SelectItem(user.getName(), user));
        }
    }

    public void persis();
}
<h:selectOneMenu value="#{userHome.user.leader}" converter="userConverter">
    <f:selectItems value="#{userHome.selectItems}"/>
</h:selectOneMenu>
@FacesConverter(forClass = User.class, value="userConverter")
public class UserConverter implements Converter {

    private  Map<String, User> userValues = new HashMap<String, User>();

    public UserConverter() {
        init();
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component,
            String value) {
        return userValues.get(value);
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        System.out.println("RAJASEKARAN "+value);
        return ((User)value).getName();
    }

    public void init() {
        UserHome userHome = new UserHome();
        for(User user:userHome.availableLeaders()) {
            userValues.put(user.getName(), user);
        }
    }
}
@facescoverter(forClass=User.class,value=“userConverter”)
公共类UserConverter实现转换器{
私有映射userValues=newhashmap();
公共用户转换器(){
init();
}
@凌驾
公共对象getAsObject(FacesContext上下文、UIComponent组件、,
字符串值){
返回userValues.get(value);
}
@凌驾
公共字符串getAsString(FacesContext上下文、UIComponent、对象值){
System.out.println(“RAJASEKARAN”+值);
返回((用户)值).getName();
}
公共void init(){
UserHome UserHome=new UserHome();
for(用户:userHome.availableLeaders()){
userValues.put(user.getName(),user);
}
}
}

尝试保存用户时,我收到错误UserEdit:j_idt18:Validation error:Value无效

您以错误的方式构造了
SelectItem
。根据,第一个参数应表示项目值(要转换和提交),第二个参数应表示项目标签(要在列表中显示)。但你却反过来指定了它们

相应地进行修正:

selectItems.add(new SelectItem(user, user.getName()));
如果这仍然不能解决问题,那么这意味着
User
类的
equals()
方法没有(正确)实现。JSF将使用它在转换后根据列表中的任何项值验证所选的
用户


与具体问题无关,知道JSF2中的
为您提供了构建列表的可能性,而无需手动构建
SelectItem
列表,这可能很有用。下面是一个实现完全相同的示例:

<f:selectItems value="#{userHome.availableLeaders}" var="user" 
    itemValue="#{user}" itemLabel="#{user.name}" />


这允许您摆脱bean构造函数中附加的
selectItems
属性和循环。

添加到BalusC的答案中:回发后,您需要确保用户实例与用于呈现所选项的实例完全相同,或者为您的用户类实现equals

代码没有显示可用的阅读器的来源,但是如果这是从DB按需获取的,那么转换器将不会转换为JSF通过
{userHome.selectItems}
解析的列表中的完全相同的对象实例


转换后,JSF将使用
equals()
方法检查是否可以在该列表中找到转换后的实例。

+1用于将SelectItem类型保留在支持bean之外,并使其使用域对象的简单列表;)嗨,在mojarra代码中,这等于发生了什么。我正在编写一个自定义组件,遇到了这个问题,我想调试mojarra代码,看看会发生什么。谢谢你,这是发生在<代码> uSeExtEngulyValueAuthValue<代码>中,实际调用“代码> >代码< >代码> Stuttudis*MatHalys