JSTL c:forEach causes @ViewScoped bean to invoke @PostConstruct on every request
Asked Answered
W

1

8

Again i see that the @PostConstruct is firing every time even though no binding attribute is used. See this code :-

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:c="http://java.sun.com/jsp/jstl/core">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form>
            <c:forEach var="item" items="#{TestBean.listItems}">
                <h:outputText value="#{item}"/>
            </c:forEach>
            <h:commandButton value="Click" actionListener="#{TestBean.actionListener}"/>
        </h:form>
    </h:body>
</html>

And this is the simplest possible bean in JSF :-

package managedBeans;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean(name="TestBean")
@ViewScoped
public class TestBean implements Serializable {

    private List<String> listItems;

    public List<String> getListItems() {
        return listItems;
    }

    public void setListItems(List<String> listItems) {
        this.listItems = listItems;
    }

    public TestBean() {

    }

    @PostConstruct
    public void init(){
        System.out.println("Post Construct fired!");
        listItems = new ArrayList<String>();
        listItems.add("Mango");
        listItems.add("Apple");
        listItems.add("Banana");
    }

    public void actionListener(){
        System.out.println("Action Listener fired!");
    }

}

Do you see any behaviour that should cause postconstruct callback to fire each time? I think JSF 2.0 is highly unstable. If it has to fire PostConstruct each and every time what purpose does @ViewScoped serve. Why not to use @RequestScoped only? I thought i have made some mistake in my application. But when i created this simplest possible in JSF, i still get this error. Am i not understanding the scopes of JSF? or are they not testing it properly? Further, if you remove c:forEach and replace it with ui:repeat, then it works fine.

Waiting for replies to confirm whether it is bug or it is intentional to stop the programmers from using jstl?

Womanize answered 16/5, 2010 at 2:23 Comment(0)
W
13

This problem has the same grounds as your previous question which is answered here: Why does @PostConstruct callback fire every time even though bean is @ViewScoped? JSF.

This is indeed a bug in JSF2. It's a chicken-egg issue. The view scoped beans are stored in the JSF view state. So the view scoped beans are only available after restore view phase. However, JSTL tags runs during restore view phase, while the view scoped beans are not available yet. This causes creation of a brand new view scoped bean instance, which is then later replaced by the real view scoped bean which was stored in the restored JSF view state.

This is reported as JSF issue 1665 and JSF spec isssue 787 which is fixed for JSF 2.2 and ported back in Mojarra 2.1.18. So, just upgrading to a minimum of Mojarra 2.1.18 should do.

If you can't upgrade, then your best bet is to use JSTL tags on request/session/application scoped beans exclusively, or to look for alternate ways for the particular functional requirement. You can replace the <c:forEach> with <ui:repeat> as you already found out.

See also:

Wrung answered 16/5, 2010 at 2:39 Comment(5)
Ok thanks BalusC. I think this too is bug only. What has jstl got to do with @PostConstruct. Anyways, i will replace it with ui:repeat as for now.Womanize
Hey BalusC. if you create a issue for this, please give me link :). So i can show to my college friends that i found bug in JSF 2.0 :Womanize
I tested and confirmed it. Here it is: javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1665Wrung
Thanks :). It is still unconfirmed. Actually both are unconfirmed in status. Don't know when will they check it.Womanize
@Wrung updated link for the issue @ java.net/jira/browse/JAVASERVERFACES-1665Amorete

© 2022 - 2024 — McMap. All rights reserved.