0

I have a simple JSF application that iterates over a list. I know I can use ui:repeat, but just for learning and comparison purposes, since c:forEach from JSTL is also part of JSF, I'd like to see how it works. What I do not understand, why does c:forEach evaluate the items for every iteration. I have a CDI bean that produces the list, and its getter is called when rendering every row of the c:forEach iteration. And even worse, it calls the getter even when c:forEach uses a variable that is set before that as shown below.

This code (part of my index.xhtml JSF file):

    Primes (over c:forEach):<br/><br/>
    <c:set var="order" value="${0}" />
    <c:set var="ps" value="${primeCalculator.primes}" />

    <c:forEach items="${ps}" var="p">
        <c:set var="order" value="${order + 1}" />
        <h:panelGrid columns="2">
            <h:outputLabel value="${order}." />
            <h:outputLabel value="${p}" />
        </h:panelGrid>
    </c:forEach>

renders the list of primes properly (n=10):

Primes (over c:forEach):

1.  2
2.  3
3.  5
4.  7

but when I do some logging from the CDI bean (@Named, @RequestScoped):

    public List<Integer> getPrimes()
    {
        System.out.println("getPrimes() n=" + n + ", cnt=" + (cnt++));
        ArrayList<Integer> result = new ArrayList<>();
        boolean compound[] = new boolean[n + 1];
        for (int i = 2; i <= n; i++)
            if (!compound[i])
            {
                result.add(i);
                for (int j = 2 * i; j <= n; j += i) compound[j] = true;
            }
        return result;
    }

I see the following in the log:

[2022-03-28T23:06:20.066+0200] (skip...) [[getPrimes() n=0, cnt=0]]
[2022-03-28T23:06:20.067+0200] (skip...) [[getPrimes() n=10, cnt=1]]
[2022-03-28T23:06:20.069+0200] (skip...) [[getPrimes() n=10, cnt=2]]
[2022-03-28T23:06:20.069+0200] (skip...) [[getPrimes() n=10, cnt=3]]
[2022-03-28T23:06:20.069+0200] (skip...) [[getPrimes() n=10, cnt=4]]
[2022-03-28T23:06:20.069+0200] (skip...) [[getPrimes() n=10, cnt=5]]
[2022-03-28T23:06:20.069+0200] (skip...) [[getPrimes() n=10, cnt=6]]

Why is the getter called for every prime that is printed out? And how could that be avoided? Yes, I have noticed when using ui:repeat, that it gets called only twice, which is still more than would make me happy, but it is better than once for each output item. I am using: Jakarta EE 9, GlassFish 6.2.3, and IntelliJ IDEA 2021.3.2 (that is JSF 3.0.1, inject api 2.0.0, cdi api 3.0, e-api 4.0, implementations weld se 4.0.2) Thanks.

Palo
  • 910
  • 12
  • 25
  • This seems to be a nice explanation, but I leave this example here, as more could be said about this, if someone would like to add more... https://stackoverflow.com/questions/2090033/why-jsf-calls-getters-multiple-times – Palo Mar 28 '22 at 22:15

0 Answers0