Как компоненты UISelectOne и UISelectMany предварительно выбирают значения по умолчанию в f:selectItems

Я знаю, как предварительно выбрать <p:selectOneMenu>в выбранном value должен быть одним из объектов из <f:selectItems>, но как этот компонент работает под капотом и можно ли изменить это поведение?

В моем случае у меня есть дубликат объекта, на самом деле это два объекта с одинаковыми значениями, но созданные дважды и выбранный объект в <p:selectOneMenu> отличается от объекта от <f:selectItems> и он не признает это. Скорее всего, я изменю свой дизайн так, чтобы он указывал на тот же объект, но в случае, если я не могу сделать это из-за устаревшего кода или чего-то еще, как я могу изменить поведение <p:selectOneMenu> что он будет сравнивать объекты по id например?

Я думал что converter ответственность за это, но когда он оказал это не входит на getAsObject только метод getAsString, так что я думаю, что есть что-то другое, но что?

Спасибо

1 ответ

Решение

Оно использует Object#equals() для этого. Вы можете изменить (исправить) это поведение, применив его соответствующим образом к вашей сущности.

private Long id;

@Override
public boolean equals(Object other) {
    return (other != null && getClass() == other.getClass() && id != null)
        ? id.equals(getClass().cast(other).id)
        : (other == this);
}

Не забывайте hashCode() удовлетворить контракт equals-hashCode.

@Override
public int hashCode() {
    return (id != null) 
        ? (getClass().hashCode() + id.hashCode())
        : super.hashCode();
}

Если по какой-то непонятной причине вы не можете изменить существующую сущность, оберните ее в собственном DTO.

Конвертер преобразует только между объектом и его уникальным String представление для использования в выводе HTML и параметрах HTTP-запроса и, следовательно, не влияет на предварительный выбор. Он влияет только на потенциальную ошибку валидации: значение не является действительной проблемой.

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

Другие вопросы по тегам