1

I have a primefaces wizard containing a ui:repeat, as follows:

<p:wizard flowListener="#{reportWizard.onFlowProcess}" widgetVar="wiz" showStepStatus="false" showNavBar="false">
    <p:tab id="problem" title="Problem">
        <p:panel header="What's the problem?" styleClass="wizardPanel">
            <p:messages />
            <h:panelGrid width="100%" columns="1">
                <ui:repeat value="#{incidentData.incidentTypes}" var="incidentTypes">
                    <p:commandButton process="@this" value="#{incidentTypes.name}" actionListener="#{reportWizard.evalProblemType}" onclick="PF('wiz').next();" styleClass="ui-priority-primary" />
                </ui:repeat>
            </h:panelGrid>
        </p:panel>
    </p:tab>
    // ... more tabs ...    
</p:wizard>

Basically, I'm just getting commandButton titles out of my database via
#{incidentData.incidentTypes}.

Previously, I had a static list of commandButtons, and it worked fine, but now that I'm using ui:repeat, it makes the page very slow (each step of the wizard takes a second or two to respond). For some reason, getIncidentTypes() is called several times when the wizard advances through each step, even though the buttons are only in the first step of the wizard, and the query should only be run once. Why is this?

Is this not the correct way to have database-driven buttons? What can I do to fix this? Thanks.

BLuFeNiX
  • 2,496
  • 2
  • 20
  • 40
  • @BalusC, sorry, you're absolutely right. I just did some debugging, and `getIncidentTypes()` is being called multiple times: Twice when the page first loads, and several more times when each `PF('wiz').next();` occurs. – BLuFeNiX Jul 10 '14 at 19:38
  • From what I've read here : https://stackoverflow.com/questions/2090033/why-jsf-calls-getters-multiple-times It looks like this is normal/expected behavior. Should I just cache the response and return it every time, or is there something better I can do? – BLuFeNiX Jul 10 '14 at 19:46
  • 1
    You should load value with a `@PostConstruct` method or something similar to load only once and return the result with `getIncicentTypes()`. – Alexandre Lavoie Jul 10 '14 at 19:53
  • @BalusC, I understand that's what I'll have to do, but it seems like a design flaw that a getter method that is only referenced to once will be called several times. – BLuFeNiX Jul 10 '14 at 20:25
  • @BalusC, I only started learning JSF last week, so it's quite likely that I'm missing something. I understand that you might want to call a getter again if your view has changed, or the user has performed some action, but I have not yet read a satisfactory explanation as to why a getter would be called multiple times in the same request, especially when it is only referenced once. It seems like a design flaw with an accepted workaround. – BLuFeNiX Jul 10 '14 at 20:46
  • @BalusC, from here: https://stackoverflow.com/questions/4281261/why-is-the-getter-called-so-many-times-by-the-rendered-attribute "The component and its renderer verifies during every step if it is allowed to render. True, this look like clumsy and inefficient. It's after all also the achilles heal of JSF. Actually, an issue was reported to JSF dev team: issue 1253 (http://java.net/jira/browse/JAVASERVERFACES-1253). It's been suggested to remove all those repeated checks and stick to the one done in `UIComponent#encodeAll()`. This may however require major changes in the API." – BLuFeNiX Jul 10 '14 at 20:53
  • @BalusC, Sorry, I did not take note of the answer's author. My point was that the aforementioned quote seems to support this being a design flaw. I still do not understand why a getter would be called multiple times in the same request, when it is only referenced once. I have already implemented the `@PostConstruct` solution, but I'd still like to understand why you think this is not a design flaw with JSF. Thanks for your time, btw. – BLuFeNiX Jul 10 '14 at 21:06

0 Answers0