5 Replies Latest reply on Apr 23, 2010 8:46 AM by kenglxn

    Bug in Weld, or JSF?

    drill

      I'm creating a fairly simple application using Weld and JSF2, running on Glassfish v3.
      However I have run into a problem which I can't get my head around. On one page I have a search field, which the result populates a h:selectOneMenu. From the h:selectOneMenu it should then be possible to select one of the results. This is were I get an error (or lack thereof, so to speak). The second request never reaches my RequestScoped bean, which I find odd.


      I have created a very simple example to illustrate. The behavior I would expect, is the search field to be populated in the h:selectOneMenu, and then the value selected here shown in the bottom line.


      Am I doing something wrong, or is this a bug somewhere?



      JSF page:


      <?xml version="1.0" encoding="UTF-8"?>
      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                      xmlns:ui="http://java.sun.com/jsf/facelets"
                      xmlns:f="http://java.sun.com/jsf/core"
                      xmlns:h="http://java.sun.com/jsf/html">
      
          <h:form id="searchform" styleClass="as_form">
              <h:inputText id="search" value="#{imTheBean.searchString}"/>
              <h:commandButton id="searchbutton" value="Search" action="#{imTheBean.doSearch}"/>
      
              <br/>
              <br/>
      
              <h:selectOneMenu id="searchResult" value="#{imTheBean.selectResult}">
                  <f:selectItems value="#{imTheBean.searchResult}"/>
              </h:selectOneMenu>
              <h:commandButton id="selectButton" value="Select" action="#{imTheBean.doSelectResult}"/>
          </h:form>
      
          <br/>
          <br/>
          You selected #{imTheBean.selectedResult}
          
      </ui:composition>



      The bean:


      import java.io.Serializable;
      import java.util.ArrayList;
      import java.util.List;
      
      import javax.enterprise.context.RequestScoped;
      import javax.inject.Named;
      
      /**
       * ImTheBean.
       */
      @RequestScoped
      @Named
      public class ImTheBean implements Serializable {
      
          private static final long serialVersionUID = -6412703392546135760L;
      
          private String searchString;
      
          private List<String> searchResult;
      
          private String selectResult;
      
          private String selectedResult;
      
      
          public void doSearch() {
              searchResult = new ArrayList<String>();
              searchResult.add(searchString);
          }
      
      
          public void doSelectResult() {
              selectedResult = selectResult;
          }
      
      
          public String getSearchString() {
              return searchString;
          }
      
      
          public void setSearchString(String searchString) {
              this.searchString = searchString;
          }
      
      
          public List<String> getSearchResult() {
              return searchResult;
          }
      
      
          public void setSearchResult(List<String> searchResult) {
              this.searchResult = searchResult;
          }
      
      
          public String getSelectedResult() {
              return selectedResult;
          }
      
      
          public void setSelectedResult(String selectedResult) {
              this.selectedResult = selectedResult;
          }
      
      
          public String getSelectResult() {
              return selectResult;
          }
      
      
          public void setSelectResult(String selectResult) {
              this.selectResult = selectResult;
          }
      }



        • 1. Re: Bug in Weld, or JSF?
          pmuir

          Any error messages in the log or in your <h:messages />?

          • 2. Re: Bug in Weld, or JSF?
            drill
            Hi Pete,

            Nothing in the log, <h:messages /> gives "searchform:searchResult: Validation Error: Value is not valid".

            I've been trying to make jsf print debug statements to the log, but haven't figured out how to set this up yet.



            Oh and if I change the bean to return a populated list for #{imTheBean.searchResult} on the first render, I'm able to submit just fine. Which is the behavior I was expecting from my example, but doesn't seem to work because I'm dynamically populating the searchResult..
            • 3. Re: Bug in Weld, or JSF?
              pmuir

              In a classic shirk of responsibility, I would suggest posting your question on the Sun JSF forum, as this seems like a JSF issue.

              • 4. Re: Bug in Weld, or JSF?
                drill

                Thanks, you were right.


                Answer: JSF needs 'getSearchResult()' to return contain the same list (or at least a list with the selected object being submitted) during the second request. Which makes it a quite a hassle to have a request scoped bean with a dynamically list for h:selectOneMenu (or the likes)...

                • 5. Re: Bug in Weld, or JSF?
                  kenglxn

                  This is true. h:select* with @RequestScoped beans doesn't play nicely together.


                  @PageScope would be nice to have for these cases.


                  Using a @ConversationScoped bean works though.




                  @ConversationScoped
                  @Named
                  public class ImTheBean implements Serializable {
                  
                      private static final long serialVersionUID = -6412703392546135760L;
                  
                      @Inject
                      Conversation conversation;
                  
                      private String searchString;
                  
                      private List<String> searchResult = new ArrayList<String>();
                  
                      private String selectResult;
                  
                      private String selectedResult;
                  
                  
                      public void doSearch() {
                          if(conversation.isTransient()) conversation.begin();
                          searchResult.add(searchString);
                      }
                  
                      ...
                  
                  }