0

After my post (Hibernate Primefaces AutoComplete text) I switched the implementation a little. But now I am facing a problem.

Even if I use an AJAX event I do not keep the selected value saved to populate a second drop down.

my CREATE.XHTML

<h:head></h:head>
<ui:debug rendered="true"/>
    <body>
        <h:form id="createAddressForm" prependId="true">
            <!-- <p:messages autoUpdate="true" /> -->
            <p:growl id="msgs" showDetail="true" />

            <h:panelGrid columns="2" style="margin-bottom:10px" cellpadding="5">
                <p:outputLabel for="countryDropDown" value="Country" />
                <p:selectOneMenu id="countryDropDown" value="#{addressController.selectedIsoCountry}" >
                    <p:ajax listener="#{addressController.onCountryChange}" update="stateDropDown" />
                    <f:selectItem itemValue="" itemLabel="Select a country"/>
                    <f:selectItems value="#{addressController.countryMap}" />
                </p:selectOneMenu>

                <p:outputLabel for="stateDropDown" value="State" />
                <p:selectOneMenu id="stateDropDown" value="#{addressController.state}" >
                    <f:selectItem itemValue="" itemLabel="Selecione a State" />
                    <f:selectItems value="#{addressController.stateMap}" />
                </p:selectOneMenu>              
            </h:panelGrid>
        </h:form>
    </body>
</html>

And this is AddressController.java

import java.util.Map;
import java.util.TreeMap;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.SessionScoped;
import javax.inject.Named;

import br.com.azulseguros.ejb.CountryEJB;
import br.com.azulseguros.entity.Country;
import br.com.azulseguros.entity.State;

@SessionScoped
@Named
public class AddressController {
    @EJB
    private CountryEJB countryEJB;

    private String selectedIsoCountry = null;

    private State state = null;

    private Map<String, String> countryMap = null;

    private Map<String, String> stateMap = null;

    @PostConstruct
    private void init() {
        Map<String, String> retorno = new TreeMap<String, String>();
        for (Country _tmp : countryEJB.findAll()) {
            retorno.put(_tmp.getName(), _tmp.getIso());
        }
        countryMap = retorno;
    }

    public Map<String, String> getCountryMap() {
        return countryMap;
    }

    public Map<String, String> getStateMap() {
        return stateMap;
    }

    public String getSelectedIsoCountry() {
        return selectedIsoCountry;
    }

    public State getState() {
        return state;
    }

    public void setSelectedIsoCountry(String selectedIsoCountry) {
        this.selectedIsoCountry = selectedIsoCountry;
    }

    public void setState(State state) {
        this.state = state;
    }

    public void setCountryMap(Map<String, String> countryMap) {
        this.countryMap = countryMap;
    }

    public void setStateMap(Map<String, String> stateMap) {
        this.stateMap = stateMap;
    }

    public void onCountryChange() {
        setStateMap(getStatesFromSelectedCountry());
    }

    private Map<String, String> getStatesFromSelectedCountry() {
        Map<String, String> retorno = new TreeMap<String, String>();
        if (selectedIsoCountry != null && !selectedIsoCountry.equals("")) {
            for (State _tmp : countryEJB.findByIso(selectedIsoCountry).getStates()) {
                retorno.put(_tmp.getName(), _tmp.getFu());
            }
        }
        return retorno;
    }
}

The EJB responsibile for finding all countries and states is working fine. There is a lot of issues with that and I do not know what to do to fix it. 1 - After I invoke the page for the first time it calls the init method 10 times; 2 - After that it evoked the method getStatesFromSelectedCountry even not choosing any country from the 1st drop down and after that evokes the init method again; 3 - When i choose a country it evokes 7 times the init method and then the getStatesFromSelectedCountry() but the selectedIsoCountry is null.

Community
  • 1
  • 1

1 Answers1

1

The bean's init method is invoked many times because you have defined the bean both as a CDI bean using javax.inject.Named, without scope, and as a JSF Managed Bean using javax.faces.bean.SessionScoped; if you intended to use CDI beans, simply replace the latter annotation with javax.enterprise.context.SessionScoped. See Why are there different bean management annotations

From a CDI point of view, the bean is by default RequestScoped, this should explain also the second issue you are experiencing.

Concerning the third issue, see this Q/A:

  1. Why is the getter called so many times by the rendered attribute?
  2. Why JSF calls getters multiple times
Community
  • 1
  • 1
perissf
  • 15,979
  • 14
  • 80
  • 117
  • 1
    Just annotating a class with `javax.faces.bean.SessionScoped` does not make it a jsf managed bean. It either needs the `@ManagedBean` annotation for that, or declaration in `faces-config.xml`. – Kukeltje Sep 28 '15 at 14:19
  • Good point @Kukeltje, but anyway that should be the cause of the problem, don't you agree? – perissf Sep 28 '15 at 14:22
  • 1
    yes, it should be the cause ,added a reference to a more detailed explanation. Marking it as a duplicate of that is not good, but I'm sure there **is** a duplicate – Kukeltje Sep 28 '15 at 14:22