3

I am aware that JSF may call a managed bean method a couple of times even if it is called only once in .xhtml. I understand that is due to encode* methods.

I would like to ask you to explain the following case to me. I have a JSF file that sort of looks like this:

<h:form id="form1">
    <h:panelGroup id="output">
        ...
        <h:commandLink...>
            <f:ajax render=":form1:output"/>
        </h:commandLink>
    </h:panelGroup>
</h:form>

All clear so far; pressing the command link rerenders a part of the page within the form panelGroup. The code follows:

<ui:repeat value="#{movieBean.categories}" var="category">
    <li>
        <h:outputLink value="index.xhtml">
            <f:param name="categoryId" value="#{category.categoryId}"/>
            <h:outputText value="#{category.description}"/>
        </h:outputLink>
    </li>
</ui:repeat>

#{movieBean.categories} //this is just a 'test line'

movieBean is request scoped.

Now, when I enter the page for the first time I get two calls to movieBean.categories. That is clear because it is called twice in the code. However, when I hit the AJAX link rendering only a part of the page (output) I get movieBean.categories from <ui:repeat> called again even though it is outside the partially rendered page area. The 'test line' is not called this time.

I performed another test. I deleted the <ui:repeat> tag leaving the 'test line' only. AJAX partial rendering dosen't call it as before.

What makes the movieBean.categories call inside a <ui:repeat> tag different than the one in 'test line'? And why is the call inside <ui:repeat> made when pressing the AJAX link even though it is outside partially rendered <h:panelGroup id="output"/> tag?

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Dzik
  • 399
  • 1
  • 5
  • 17
  • Please read message formatting rules in help (`?`) of the message editor. Escaping HTML tags is clumsy and absolutely not needed :) – BalusC Dec 16 '11 at 15:13
  • I'm not sure why you're worrying about this as getter calls are extraordinary cheap, but if it is because your getter is not just a getter but is doing much more than just returning data, then please read this: http://stackoverflow.com/questions/2090033/why-jsf-calls-getters-multiple-times/2090062#2090062 – BalusC Dec 16 '11 at 15:16
  • getCategories fetches data from a database. Placing in in @PostConstruct would change much since my bean is request scoped and AJAX would create it again. I though that partial rendering wouldn't call getCategories since it is not in the rendered area. It's not a problem, though. I just wanted to know why it happens and got the answer below. – Dzik Dec 16 '11 at 15:35
  • Thanks for the link. I'll check it thoroughly. – Dzik Dec 16 '11 at 15:38
  • You should never do any business job in JSF managed bean getters. See also the link (and all of its sublinks). You need to put beans which are bound to ajax forms in the view scope by @ViewScoped. See also [Managed bean scopes](http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html#ManagedBeanScopes) – BalusC Dec 16 '11 at 15:41

1 Answers1

3

I'm pretty sure that "redundant" call is made within a phase where JSF rebuilds element tree to store POST data into appropriate elements.

So you basically have two getter calls per request if you stay on the page. First one to store new form values, then to render page content.

DRCB
  • 2,111
  • 13
  • 21
  • Thanks for the answer. I guess I will have to look at all the JSF phases more closely. – Dzik Dec 16 '11 at 15:36
  • I was seeing a similar situation where a ui:repeat appeared to be getting processed despite not being part of the partial processing or partial render. If it's rebuilding the element tree to store potential data, then that explains things. – brantgurga Feb 18 '13 at 19:06