Why does @PostConstruct callback fire every time even though bean is @ViewScoped? JSF

前端 未结 5 608
没有蜡笔的小新
没有蜡笔的小新 2020-11-30 01:19

I am using datatable on page and using binding attribute to bind it to my backing bean. This is my code :-


         


        
相关标签:
5条回答
  • 2020-11-30 01:41

    As other said, I would say that the best thing to do is to drop component binding (you don't need it here).

    But I would add that you can achieve the same as you're trying to do in a more object-oriented fashion by using action parameters, like this:

    <h:commandButton value="Click" action="#{testBean.action(item)}"/>
    

    ... and in your java code:

      public void action(Item item){
        System.out.println("Clicked!!" + item);
    }
    
    0 讨论(0)
  • 2020-11-30 01:47

    Interesting, when you're using component binding on a view scoped bean, the view scope breaks.

    I am not sure if that is a bug in JSF2, I would have to read the entire JSF2 specification first. As far now your best bet is to drop the component binding for now and pass the selected item via new EL 2.2 method argument syntax:

    <h:dataTable var="item" value="#{testBean.stringCollection}">
        <h:column>
            <h:outputText value="#{item}"/>
        </h:column>
        <h:column>
            <h:commandButton value="Click" action="#{testBean.action(item)}"/>
        </h:column>
    </h:dataTable>
    

    See also:

    • How can I pass selected row to commandLink inside dataTable?
    • Invoke direct methods or methods with arguments / variables / parameters in EL
    • Benefits and pitfalls of @ViewScoped

    Update (Dec 2012): 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, the binding attribute 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 1492 and JSF spec isssue 787 which will be fixed for JSF 2.2. Until then, your best bet is to use binding on request scoped beans exclusively, or to look for alternate ways for the particular functional requirement.


    Update (Mar 2015): The JSF 2.2 fix was backported to Mojarra 2.1.18. So if you're still using JSF 2.0/2.1, you'd best upgrade to at least that version. See also a.o. What is component binding in JSF? When it is preferred to be used? and JSTL in JSF2 Facelets... makes sense?

    0 讨论(0)
  • 2020-11-30 01:55

    The balusc's answer helped me a lot, i would like to say that i had that bug with mojarra version 2.1.7, i am currently using 2.1.29-01 released in january-2015 and this bug is fixed, my problem was binding a tabview to a viewscoped bean. With this version I dont have that bug and binding and postconstruct is working fine. I use Jboss 5.2 and i have to use mojarra 2.1.x so i hope this answer help other people in the same situation.

    http://mvnrepository.com/artifact/com.sun.faces/jsf-api/2.1.29-01 http://mvnrepository.com/artifact/com.sun.faces/jsf-impl/2.1.29-01

    0 讨论(0)
  • 2020-11-30 01:56

    If you have a viewscoped bean and if you want to retain values that were entered on the form or don't want postconstruct fired, you should return null from your action method.

    If you return some outcome (e.g. invalid) and then point the invalid outcome to the same page using faces-config.xml, then the viewscoped bean gets recreated and thus it causes postconstruct to fire again.

    0 讨论(0)
  • 2020-11-30 02:01

    Other solution:

    • Binding the HtmlDataTable in a request scope bean.
    • Inject this request scope bean in the view scope bean.

    JBoss Seam use this solution for binding JSF componentes to a conversation scope component.

    0 讨论(0)
提交回复
热议问题