3 Replies Latest reply on Dec 17, 2007 9:22 AM by Pete Muir

    Caching select items in UISelectItems - Bug?

    Kahli Burke Newbie

      Hi,

      We found a problem that started occurring in our application when we upgraded to Seam 2.0.0GA. This occurs when using a List to back <s:selectItems> and using an <h:selectOneMenu> (or listbox).

      for example using this component:

      @Name("testComp")
      @Scope(ScopeType.CONVERSATION)
      public class TestComp {
      
      
       private List<String> testStrings = new ArrayList<String>();
      
       private String selectedString;
      
       public List<String> getStrings() {
       return testStrings;
       }
      
       public String getSelectedString() {
       return selectedString;
       }
      
       public List<String> getSelectedStrings() {
       return selectedStrings;
       }
      
       public void addString() {
       testStrings.add("String "+testStrings.size());
       }
      
       public void removeString() {
       testStrings.remove(testStrings.size()-1);
       }
      
       public void setSelectedString(String selectedString) {
       this.selectedString = selectedString;
       }
      }
      
      


      and for the UI:

      <h:selectOneListbox value="#{testComp.selectedString}">
       <s:selectItems value="#{testComp.strings}" var="str" label="#{str}"/>
      </h:selectOneListbox><br/>
      <h:commandLink value="add" action="#{testComp.addString}"/><br/>
      <h:commandLink value="remove" action="#{testComp.removeString}"/><br/>
      


      Note that I'm assuming that this is all happening within a conversation so that the state of TestComp is the same from request to request. The issue appears to be as a result of only conditionally building the list of select items in UISelectItems. Previously they were always rebuilt in getValue. The problem is that the getValue() method is called during the validation phase, and then when it gets called again, the condition:

      if (value == null || originalValue == null || !originalValue.equals(super.getValue()))
       {
      


      is always false. This is true because even though an attempt is made to check whether originalValue is different than the superclass' stored value, in this case they will always be the same object instance, the underlying list.

      I thought about whether it would be sensible to try to determine whether the contents of the list are the same, but at that point we're reaching diminishing returns if the goal was to reduce the overhead of getValue().

      I've worked around this for now by creating a duplicate JSF component class, removing that conditional, and using that instead of <s:selectItems>

      Am I making any incorrect assumptions about the way this should all work, or should I enter a bug report for it?