4 Replies Latest reply on Aug 10, 2007 7:43 AM by rodrigotico

    selectItems strange behavior

    rodrigotico

      Hello all,

      I am trying to get a object from a <h:selectOneMenu> component and getting a strange behavior.

      My entities are:

      Client >1:1> Address >n:1> City <n:1> State

      In my user interface I have a selectMenu with the states registered on the database and another selectMenu with the cities of the state selected. When the user select the state I fill the cities box. This is working very good.

      The problem is when I try to press the button of the form to save the client:
      If the the city box don´t have a city selected, the action is called as expected.
      If the city box has a city selected, the form is reloaded without call the action method of the button.

      I don´t know what to do. I am trying to inject client.address.city, is that possible?

      I´m putting here all the code of a test project that I created to test it.

      Thanks.

      My Session Bean (insertClient)

      @Stateless
      @Name("insertClient")
      public class InsertClientAction implements InsertClient {
      
       @In Client client;
       @In StateDAO stateDAO;
       private ArrayList<State> states;
       private ArrayList<City> cities;
      
       public String viewClient() {
       stateDAO.createInitDB();
       return "/client.xhtml";
       }
      
       public void saveClient() {
       System.out.println("Client´s Name: " + client.getName());
       System.out.println("Client´s Street: " + client.getAddress().getStreet());
       System.out.println("Client´s City: " + client.getAddress().getCity().getName());
       System.out.println("Client´s State: " + client.getAddress().getCity().getState().getName());
       }
      
       public ArrayList<State> getStates() {
       states = new ArrayList<State>(stateDAO.getAll());
       return states;
       }
      
       public ArrayList<City> getCities() {
       return cities;
       }
      
       public void updateCities(ValueChangeEvent event) {
       State state;
       try {
       state = (State) event.getNewValue();
       } catch (Exception e) {
       return;
       }
       if (state!=null) {
       System.out.println("State: " + state.getName());
       cities = new ArrayList<City>(state.getCities());
       }
       }
      }
      


      Session Bean Interface

      @Local
      public interface InsertClient {
      
       public String viewClient();
       public void saveClient();
       public Collection <State> getStates();
       public Collection <City> getCities();
       public void updateCities(ValueChangeEvent event);
      
      }
      


      My User Interface: (client.xhtml)


       <h:panelGrid columns="2">
       <h:outputText value="Name:"></h:outputText>
       <h:inputText value="#{client.name}"></h:inputText>
       <h:outputText value="Street:"></h:outputText>
       <h:inputText value="#{client.address.street}"></h:inputText>
      
       <h:outputText value="State:"></h:outputText>
      
       <h:selectOneMenu value="#{state}" id="state" valueChangeListener="#{insertClient.updateCities}">
       <s:selectItems value="#{insertClient.states}" var="state" label="#{state.name}" noSelectionLabel="Please Select..."/>
       <a:support event="onchange" reRender="city" ></a:support>
       <s:convertEntity />
       </h:selectOneMenu>
      
       <h:outputText value="City:"></h:outputText>
       <h:selectOneMenu value="#{client.address.city}" id="city">
       <s:selectItems value="#{insertClient.cities}" var="city" label="#{city.name}" noSelectionLabel="Please Select..." />
       <s:convertEntity />
       </h:selectOneMenu>
      
       <h:commandButton action="#{insertClient.saveClient}" value="ok h:"></h:commandButton>
       <s:button action="#{insertClient.saveClient}" value="ok s:"></s:button>
      
       </h:panelGrid>
      


      Client Entity:

      @Entity
      @Name("client")
      @AutoCreate
      public class Client {
      
       private Long id;
       private String name;
       private Address address;
      
       @Id
       @GeneratedValue(strategy=GenerationType.AUTO)
       public Long getId() {
       return id;
       }
      
       public void setId(Long id) {
       this.id = id;
       }
      
       public Client() {
       address = new Address();
       }
      
       @Column(nullable=false, length=200)
       public String getName() {
       return name;
       }
      
       public void setName(String name) {
       this.name = name;
       }
      
       @OneToOne (cascade=CascadeType.ALL)
       public Address getAddress() {
       return address;
       }
      
       public void setAddress(Address address) {
       this.address = address;
       }
      }
      


      Address Entity:

      @Entity
      @Name("address")
      public class Address {
      
       private Long id;
       private String street;
       private City city;
      
      
       @Id
       @GeneratedValue(strategy=GenerationType.AUTO)
       public Long getId() {
       return id;
       }
      
       public void setId(Long id) {
       this.id = id;
       }
      
       @Column(nullable=false, length=200)
       public String getStreet() {
       return street;
       }
      
       public void setStreet(String street) {
       this.street = street;
       }
      
       @ManyToOne
       @JoinColumn(name="city_id")
       public City getCity() {
       return city;
       }
      
       public void setCity(City city) {
       this.city = city;
       }
      
      }
      


      City Entity:

      @Entity
      @Name("city")
      @AutoCreate
      public class City implements Serializable {
      
       private static final long serialVersionUID = -8910258028221144179L;
       private Long id;
       private String name;
       private State state;
      
      
       @Id
       @GeneratedValue(strategy=GenerationType.AUTO)
       public Long getId() {
       return id;
       }
      
       public void setId(Long id) {
       this.id = id;
       }
      
       public City() {
       state = new State();
       }
      
       @Column(nullable=false, length=40)
       public String getName() {
       return name;
       }
      
       public void setName(String name) {
       this.name = name;
       }
      
       @ManyToOne
       @JoinColumn(name="state_id")
       public State getState() {
       return state;
       }
      
       public void setState(State state) {
       this.state = state;
       }
      
      }
      


      State Entity:

      @Entity
      @Name("state")
      @AutoCreate
      public class State implements Serializable {
      
       private static final long serialVersionUID = -8286496968276572340L;
       private long id;
       private String name;
       private Collection<City> cities;
      
       @Id
       @GeneratedValue(strategy=GenerationType.AUTO)
       public Long getId() {
       return id;
       }
      
       public void setId(Long id) {
       this.id = id;
       }
      
       @Column(nullable=false, length=40)
       public String getName() {
       return name;
       }
      
       public void setName(String name) {
       this.name = name;
       }
      
       @Override
       public boolean equals(Object obj) {
       if (obj instanceof State) {
       if (((State)obj).getId()==getId())
       return true;
       return false;
       }
       return super.equals(obj);
       }
      
       @Override
       public String toString() {
       return super.toString();
       }
      
       @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
       @JoinColumn(name="state_id")
       public Collection<City> getCities() {
       return cities;
       }
      
       public void setCities(Collection<City> cities) {
       this.cities = cities;
       }
      
      }
      


      The State DAO:

      @Name("stateDAO")
      @AutoCreate
      public class StateDAO extends EntityHome<State> {
      
       @Transactional
       public Collection<State> getAll() {
       return getEntityManager().createQuery("from State order by id").getResultList();
       }
      
       @Transactional
       public void createInitDB() {
       EntityManager em = getEntityManager();
      
       State california = new State();
       california.setName("California");
       em.persist(california);
       State florida = new State();
       florida.setName("Florida");
       em.persist(florida);
      
       City city;
       city = new City();
       city.setName("Los Angeles");
       city.setState(california);
       em.persist(city);
      
       city = new City();
       city.setName("San Francisco");
       city.setState(california);
       em.persist(city);
      
       city = new City();
       city.setName("Miami");
       city.setState(florida);
       em.persist(city);
      
       city = new City();
       city.setName("Orlando");
       city.setState(florida);
       em.persist(city);
       }
      }
      


        • 1. Re: selectItems strange behavior
          pmuir

          Make sure you have a h:messages component on the page and see what errors it gives.

          • 2. Re: selectItems strange behavior
            rodrigotico

            Thanks for your answer Pete, I put h:messages component.
            If a city is selected, the error is "value is not valid" when I submit the form, but I don't know why.

            Is that possible: inject the client's address with the selected city?

            Thanks.

            Here is the complete code of the page:

            <?xml version='1.0' encoding='ISO-8859-1'?>
            <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
             "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
            
            <rich:panel xmlns="http://www.w3.org/1999/xhtml"
             xmlns:s="http://jboss.com/products/seam/taglib"
             xmlns:ui="http://java.sun.com/jsf/facelets"
             xmlns:f="http://java.sun.com/jsf/core"
             xmlns:h="http://java.sun.com/jsf/html"
             xmlns:a="https://ajax4jsf.dev.java.net/ajax"
             xmlns:rich="http://richfaces.ajax4jsf.org/rich">
            
             <h:messages></h:messages>
             <h:form>
             <h:panelGrid columns="2">
             <h:outputText value="Name:"></h:outputText>
             <h:inputText value="#{client.name}"></h:inputText>
             <h:outputText value="Street:"></h:outputText>
             <h:inputText value="#{client.address.street}"></h:inputText>
            
             <h:outputText value="State:"></h:outputText>
            
             <h:selectOneMenu value="#{state}" id="state"
             valueChangeListener="#{insertClient.updateCities}">
             <s:selectItems value="#{insertClient.states}" var="state"
             label="#{state.name}" noSelectionLabel="Please Select..." />
             <a:support event="onchange" reRender="city"></a:support>
             <s:convertEntity />
             </h:selectOneMenu>
            
             <h:outputText value="City:"></h:outputText>
             <h:selectOneMenu value="#{client.address.city}" id="city">
             <s:selectItems value="#{insertClient.cities}" var="city"
             label="#{city.name}" noSelectionLabel="Please Select..." />
             <s:convertEntity />
             </h:selectOneMenu>
            
             <h:commandButton action="#{insertClient.saveClient}" value="ok h:"></h:commandButton>
             <s:button action="#{insertClient.saveClient}" value="ok s:"></s:button>
            
             </h:panelGrid>
             </h:form>
            
            </rich:panel>
            
            


            • 3. Re: selectItems strange behavior
              pmuir
              • 4. Re: selectItems strange behavior
                rodrigotico


                I put on a long-running conversation and now everything is working good!

                Thank you Pete!