Yichz
Yichz

Reputation: 9671

Same @PostConstruct calling twice, data not surviving

Hi I'm learning JSF/Primefaces. whenever user click on a link it should forward to the edit page with the information, but it's empty.

I tried to debug, following flow happens:

I found this but I'm now only using jsf annotation to manage view beans

QuoteStatusList.java

@ManagedBean
@RequestScope    
public class QuoteStatusList extends BasePage implements Serializable {
        @PostConstruct
        public void init(){
            log.debug("initing...");
        }
    ...
    }

QuoteStatusForm.java

@ManagedBean
@ViewScope
    public class QuoteStatusForm extends BasePage implements Serializable {
    @PostConstruct
        public void init(){
            log.debug("initing...");
        }

    public String edit() {
            log.debug("editing..");
             if (idQuoteStatus != null && idQuoteStatus != 0) {
                quoteStatus = quoteStatusManager.get(idQuoteStatus);
            } else {
                quoteStatus = new QuoteStatus();
            }  
            return "edit";
        }

    }

BasePage.java

@ManagedBean
@RequestScoped
public class BasePage {
    //nothing is injected
//no other @postConstruct function
}

QuoteStatusList.xhtml

<h:commandLink action="#{quoteStatusForm.edit}" value="#{quoteStatus.idQuoteStatus}">
                        <f:param name="idQuoteStatus" value="#{quoteStatus.idQuoteStatus}"/>
                    </h:commandLink>

faces-config.xml

 <navigation-rule>
        <from-view-id>/quoteStatusList.xhtml</from-view-id>
        <navigation-case>
            <from-outcome>edit</from-outcome>
            <to-view-id>/quoteStatusForm.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>
    <navigation-rule>
        <from-view-id>/quoteStatusForm.xhtml</from-view-id>
        <navigation-case>
            <from-outcome>edit</from-outcome>
            <to-view-id>/quoteStatusForm.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>

Upvotes: 3

Views: 1412

Answers (1)

kolossus
kolossus

Reputation: 20691

What you're experiencing is appropriate behaviour for @RequestScoped and @ViewScoped beans.

  1. @RequestScoped - Beans of this scope will not survive a redirect/forward to another page. That means that if you're on a page backed by a bean of this scope, whenever you issue a new HTTP request (either ajax, a full-on page refresh, or a redirect), the instance of that bean you're working on is destroyed, voided, ceases to exist. Along with all its member variables

  2. @ViewScoped - Beans of this scope will also not survive a full redirect/forward. They will however survive page refreshes and ajax. What this means is that, as long as you stay on the same page (backed by a @ViewScoped bean), don't return any navigation case, you're guaranteed to be working with the same instance of the bean.


How are these beans supposed to communicate then? If leaving one page means that you lose everything the backing bean contains, what your options (you should be asking)? Well, there are a number of ways that JSF beans can communicate. Read through the gospel on inter-bean communication


So what's happening in your case

  1. QuoteStatusList list is destroyed when you navigate away from the page that it backs. This also means that when you come back, you're dealing with a brand new instance of that bean (and that's why init is called twice)

  2. QuoteStatusForm was destroyed because you returned edit from that bean, causing the instance you're working with to be destroyed and recreated on page load


What to do:

To avoid destroying QuoteStatusForm, you can just return null from edit

Upvotes: 1

Related Questions