JSF 2.0 - selectOneMenu по умолчанию равно 0, когда пусто - PullRequest
2 голосов
/ 11 ноября 2011

Для моего проекта я хочу реализовать комбинированный список с h: selectOneMenu . Я прочитал много постов о том, как правильно обрабатывать selectOneMenu и как реализовать собственный конвертер. В комбинированном ящике должен храниться идентификатор ( Long ) из другой таблицы БД (с именем fk_ID), для которой установлено ограничение. Пока что все работает, как и планировалось. Теперь к моей проблеме:

Столбец fk_ID является необязательным, поэтому первым параметром в выпадающем списке является f: selectItem без значения, помеченного как "выбирать ...". Когда я сохраняю форму и изменяю значение, все в порядке, за исключением случаев, когда я возвращаю его обратно «выбрать ...». Я получаю ошибку: нарушение целостности ограничения .

Я также обнаружил проблему: преобразователь возвращает ноль , как и предполагалось, но бин получает Long 0 .

XHTML:

<h:selectOneMenu value="#{userBean.selectedModel.fk_id}"
    id="combobox">
    <f:selectItem itemLabel="choose ..." />
    <f:selectItems
        value="#{userBean.items}"
        var="item"
        itemLabel="#{item.value}"
        itemValue="#{item.id}"
    />
    <f:converter converterId="userConverter" />
</h:selectOneMenu>

Пользовательский конвертер:

@FacesConverter(value = "userConverter")
public class UserConverter implements Converter {
    @Override
    public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
        if (arg2 != null && !arg2.equals("null"))
            return Long.valueOf(arg2);

        return null;
    }
    @Override
    public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
        return String.valueOf(arg2);
    }
}

Боб (очень короткая версия):

@Named(value = "userBean")
public class UserController implements Serializable {

    @Getter
    @Setter
    private UserModel selectedModel;

    @Getter
    @Setter
    private List<UserModel> items;

    public void saveModel() {
        selectedModel = userService.saveModel(selectedModel);
    }
}

Проблема в том, что fk_id имеет значение Long 0 , но должно быть null . Я могу решить проблему, написав

if (selectedModel.getFk_id() == 0)
    selectedModel.setFk_id(null);

, но это не решение, с которым мне удобно.

Мой вопрос: почему значение null , которое возвращает конвертер, Long 0 в методе saveModel () ?

1 Ответ

5 голосов
/ 11 ноября 2011

Этот конвертер не нужен и не имеет смысла (я бы ожидал, что UserConverter будет конвертировать между User и String, а не между Long и String). Убери это.

Теперь вам нужно указать JSF интерпретировать пустые строки, переданные как null. Добавьте следующее к вашему web.xml:

<context-param>
    <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
    <param-value>true</param-value>
</context-param>

Это должно решить проблему на большинстве контейнеров. Но если вы используете Tomcat или его форк / клон (JBoss AS, WebSphere AS и т. Д.) И / или контейнер использует реализацию синтаксического анализатора Apache EL, то вам также необходимо добавить следующий аргумент в его аргументы запуска VM:

-Dorg.apache.el.parser.COERCE_TO_ZERO=false

Это предотвратит синтаксический анализатор Apache EL для принудительного приведения переданного значения к значению по умолчанию примитива, даже если вы используете примитивный тип оболочки в качестве свойства.

Смотри также:


Не имеет отношения к конкретной проблеме, у вас там нет выпадающего списка. Это просто простой выпадающий список. Комбо-бокс - это редактируемый выпадающий список. Получите ваши условия правильно;)

...