PropertyNotFoundException при условно визуализированных подклассах в ui: repeat

У меня есть суперкласс Person:

public class Person {
    public abstract Type getType();
}

У меня есть 2 подкласса:

public class JuridicalPerson extends Person {
    public Type getType() {
        return Type.JP;
    }
    public List<JuridicalBelong> getJuridicalBelongs() {
        return juridicalBelongs;
    }
}
public class NaturalPerson extends Person {
    public Type getType() {
        return Type.NP;
    }
    public List<NaturalBelong> getNaturalBelongs() {
        return naturalBelongs;
    }
}

JuridicalBelong и NaturalBelong имеют разные свойства и не могут быть подклассы.

Я имею их в List<Person>, который я хотел бы представить в JSF/Facelets следующим образом:

<ui:repeat value="#{bean.persons}" var="person">
    <h:panelGroup rendered="#{person.type eq 'JP'}">
        <ui:repeat value="#{person.juridicalBelongs}" var="juridicalBelong">
            ...
        </ui:repeat>
    </h:panelGroup>
    <h:panelGroup rendered="#{person.type eq 'NP'}">
        <ui:repeat value="#{person.naturalBelongs}" var="naturalBelong">
            ...
        </ui:repeat>
    </h:panelGroup>
</ui:repeat>

Однако это вызывает следующее исключение:

javax.el.PropertyNotFoundException: класс "com.example.NaturalPerson" не имеет свойства "юридические символы".

Как это возможно? Согласно моему условию rendered

<h:panelGroup rendered="#{person.type eq 'JP'}">

он должен игнорировать NaturalPerson, правильно?

Ответ 1

Это вызвано ошибкой в ​​управлении состоянием Mojarra <ui:repeat>, которая будет отображаться при использовании компонентов EditableValueHolder (полей ввода) внутри <ui:repeat>. Это исправлено по вопросу 3215. Исправление доступно в Mojarra 2.2.7, а для JSF 2.0/2.1 - back to Mojarra 2.1.29 как за номер 3221. Так что обновление до, по крайней мере, той версии (или только последней версии, доступной по домашней странице Mojarra).

В противном случае лучше всего заменить <ui:repeat> на <c:forEach>.

Ответ 2

В моем случае у меня не было возможности обновить версию Mojarra и избежать c: forEach (что вызывает много побочных эффектов при использовании с ui опционально отображаемыми компонентами) Я заменил ui: repeat с ap: dataList, и он работал, Вам нужно будет немного стилизовать CSS, чтобы скрыть пули, но я думаю, что это стоит того. Я надеюсь, что это поможет кому-то;)