null

Помогите Даше найти потерянное выбранное значение в selectOneMenu

Когда мы разрабатываем веб-приложения с использованием JavaServer Faces (JSF), нам часто приходится разбираться с неожиданными нюансами поведения jsf-компонентов.

Сегодня поговорим о следующей проблеме с selectOneMenu: выбранное значение выпадающего списка отображается пустым, даже если в базе данных есть все необходимые данные, а в поле бина выбрано корректное значение. 

Пример

Рассмотрим пример выпадающего списка, где пользователь выбирает исполнителя задачи:
 

<p:selectOneMenu id="executor" value="#{taskBean.currentTask.executor}"
                 converter="#{taskBean.executorConverter}" effect="fade"
                 required="true" requiredMessage="Пожалуйста, выберите исполнителя">
    <p:ajax event="change" process="@this" update="@this"/>
    <f:selectItem itemLabel="-- Выберите исполнителя --" itemValue="#{null}"/>
    <f:selectItems value="#{taskBean.executors}" var="executor"
                   itemLabel="#{executor.name}" itemValue="#{executor}"/>
</p:selectOneMenu>

 

В этом коде мы отображаем список исполнителей задач, загружаемых из базы данных. При загрузке страницы компонент должен установить текущего исполнителя, выбранного ранее. Однако иногда оно оказывается пустым, хотя данные о текущем исполнителе есть, и выбранное значение не null.

Причина проблемы

Проблема заключается в том, что JSF, когда рендерит компонент selectOneMenu, использует метод equals для сравнения объектов. Если у объекта, который хранится в модели (currentTask.executor), и объекта, который пришел из списка (executors), методы equals и hashCode не реализованы корректно, то даже при идентичных данных JSF не сможет их сопоставить. В результате компонент посчитает, что выбранный элемент отсутствует, и отобразит пустое значение.

Мораль: всегда переопределяйте equals и hashCode для объектов, которые могут быть использованы в UI, сгенерированном с помощью JSF-компонентов.

 

Вперед

Коротко о себе:

Работаю программистом в компании Tune-it.

Занимаюсь какими-то проектами, связанными с чем-то.