Ошибка проверки JSF-конвертора: значение недействительно для SelectOneMenu UIComponent
Я использую managedBean userHome в requestScope, в котором объект "пользователь" будет сохраняться.
У пользователя есть столбец лидера, который отображается в отношении ManyToOne. Мой код выглядит следующим образом:
@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();
}
User.java
public class User {
@Id
@Column
private Integer id;
@Column
privat String name;
@ManyToOne
private User leader;
}
Я пытаюсь получить значение этого лидера через h:selectOneMenu
, как этот
<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);
}
}
}
При попытке сохранить пользователя я получаю сообщение об ошибке UserEdit: j_idt18: Ошибка проверки: значение недействительно
Ответы
Ответ 1
Добавление в ответ BalusC: после обратной передачи вам нужно убедиться, что экземпляры пользователя либо точно такие же, как и для рендеринга выбранных элементов, или что вы реализуете равные для своего класса User.
Код не показывает, откуда приходит availableLeaders
, но если он извлекается из БД по требованию, тогда конвертер не будет преобразовываться в тот же экземпляр объекта, который в списке, разрешенном JSF через #{userHome.selectItems}
.
После преобразования JSF проверит, может ли преобразованный экземпляр быть найден в этом списке с помощью метода equals()
.
Ответ 2
Вы построили SelectItem
неверный путь. Согласно документации class, первый аргумент должен представлять значение элемента (которое должно быть преобразовано и представлено), а второй аргумент должен представлять (который должен отображаться в списке). Но вы указали их наоборот.
Исправьте его соответствующим образом:
selectItems.add(new SelectItem(user, user.getName()));
Если это еще не устраняет проблему, значит, метод equals()
класса User
не реализован (правильно). JSF будет использовать его для проверки выбранного User
по отношению к любому из значений элемента списка после преобразования.
Несвязанный к конкретной проблеме, может быть полезно знать, что <f:selectItems>
в JSF2 предлагает вам возможность создать список без необходимости создания списка SelectItem
вручную. Вот пример, который достигает точно такой же:
<f:selectItems value="#{userHome.availableLeaders}" var="user"
itemValue="#{user}" itemLabel="#{user.name}" />
Это позволяет избавиться от дополнительного свойства selectItems
и цикла в конструкторе bean.