PropertyNotFoundException на условно отображаемых подклассах в пользовательском интерфейсе: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' не имеет свойства 'juridicalBelongs'.
Как это возможно? Согласно моему rendered
состояние
<h:panelGroup rendered="#{person.type eq 'JP'}">
это следует игнорировать NaturalPerson
, право?
2 ответа
Это вызвано ошибкой в управлении государством Мохарры <ui:repeat>
который выставит при использовании EditableValueHolder
компоненты (поля ввода) внутри <ui:repeat>
также. Это исправлено в соответствии с проблемой 3215. Исправление доступно в Mojarra 2.2.7 и для JSF 2.0/2.1, перенесенных в Mojarra 2.1.29 в соответствии с проблемой 3221. Поэтому обновление по крайней мере до этой версии (или только до последней версии, доступной на домашней странице Mojarra) должно сделать это.
В противном случае вам лучше всего заменить <ui:repeat>
от <c:forEach>
,
В моем случае у меня не было возможности обновить версию Mojarra, и чтобы избежать c:forEach (который вызывает много побочных эффектов при использовании с компонентами, визуализируемыми с пользовательским интерфейсом), я заменил ui:repeat на a p:dataList, и это сработало. Вы должны будете сделать некоторые стили CSS, чтобы скрыть маркеры, но я думаю, что это стоит того. Надеюсь, это кому-нибудь поможет;)