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

Gna*_*nam 10 jsf jpa

我在requestScope中使用managedBean userHome,其中实体'user'将被保留.用户具有以ManyToOne关系映射的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();
}
Run Code Online (Sandbox Code Playgroud)

User.java

public class User {
    @Id
    @Column
    private Integer id;

    @Column
    privat String name;

    @ManyToOne
    private User leader;
}
Run Code Online (Sandbox Code Playgroud)

我试图通过h:selectOneMenu这样的方式获得这个领导者的价值

<h:selectOneMenu value="#{userHome.user.leader}" converter="userConverter">
    <f:selectItems value="#{userHome.selectItems}"/>
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)

我的转换器看起来像这样

@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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在尝试保存用户时我收到错误UserEdit:j_idt18:验证错误:值无效

Arj*_*jms 14

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

代码没有显示availableLeaders来自哪里,但是如果这是从按需数据库获取的,那么转换器将不会转换为JSF通过的列表中完全相同的对象实例#{userHome.selectItems}.

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


Bal*_*usC 8

你构造SelectItem错误的方式.根据类的文档,第一个参数应该表示项目值(将被转换和提交),第二个参数应该表示项目标签(将在列表中显示).但是你反过来指定了它们.

相应修复:

selectItems.add(new SelectItem(user, user.getName()));
Run Code Online (Sandbox Code Playgroud)

如果仍然无法解决问题,那么这意味着类的equals()方法User没有(正确)实现.转换后,JSF将使用它来User对列表中的任何项目值验证所选项.


具体问题无关,知道<f:selectItems>在JSF2中为您提供构建列表的可能性可能是有用的,而无需SelectItem手动构建列表.这是一个完全相同的例子:

<f:selectItems value="#{userHome.availableLeaders}" var="user" 
    itemValue="#{user}" itemLabel="#{user.name}" />
Run Code Online (Sandbox Code Playgroud)

这允许您摆脱selectItemsbean构造函数中的附加属性和循环.