2

in a way similar to here I am using an abstract class to type the item set list of ui:repeat. Concrete subclasses override the getType() method, that is used to conditionally render the respective subtype with its particular properties:

<!-- AbstractAction Rule#getActions() -->
<ui:repeat value="#{rule.actions}" var="action">
  <!-- render when "action" instance of NotificationAction -->
  <h:panelGroup rendered="#{action.type == 'notification'}"> 
    ... UI for NotificationAction properties 
  <h:panelGroup rendered="#{action.type == 'callback'}"> 
    ...

When run on Glassfish 3 there is an error about properties not being defined on list members of other subclasses (PropertyNotFoundException), which occurs in a branch that is actually switched off by the rendered property. c:forEach/c:choose do not seem appropriate. Any ideas how to make the rendering really conditional and bypass the property checking are highly appreciated!

Thank you. Jaro

Community
  • 1
  • 1
jpullmann
  • 31
  • 1
  • 3
  • Duplicate of http://stackoverflow.com/questions/22613193/javax-el-propertynotfoundexception-when-submitting-uirepeat-with-conditionally/ – BalusC Aug 12 '14 at 18:38

1 Answers1

1

after some testing it turned out, that the ui:repeat component itself caused the error. Despite being in the final RenderResponse phase it tries to save the status of its child input components. Here a shortened exception dump:

Caused by: javax.el.PropertyNotFoundException: ... The class FOO does not have a readable property 'BAR'.
        at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:104)        
        at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:343)
        at com.sun.faces.facelets.component.UIRepeat.setIndex(UIRepeat.java:428)
        at com.sun.faces.facelets.component.UIRepeat.process(UIRepeat.java:522)
        at com.sun.faces.facelets.component.UIRepeat.encodeChildren(UIRepeat.java:926)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1613)
        at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:273)
        at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:127)
        at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)

Hereby the rendered condition is ignored and the EL interpreter complains about non-existent properties. There is a simple solution by using the h:dataTable iterator with a single column instead:

<h:dataTable value="#{rule.systemActions}" var="action">
        <c:set var="name" value="#{action.class.simpleName.toLowerCase()}" />
        <h:column>
            <h:panelGroup rendered="#{name == 'notification'}">
                    <h:outputLabel for="phone">Phone:</h:outputLabel>
                    <h:inputText value="#{action.phone}" id="phone" />
            </h:panelGroup>
            <h:panelGroup rendered="#{name == 'reminder'}">
              ...
            </h:panelGroup>
        </h:column>
  </h:dataTable>

Cheers.

Jaro

jpullmann
  • 31
  • 1
  • 3