arraysjsfjsf-2collectionsselectmanymenu

Why is UISelectMany not returning a collection on a generic property?


I have a JSF page that contains a <h:selectManyMenu> element. The value attribute points to a generic object defined in a subclass as type ArrayList<String>. According to the java documentation the UISelectMany should return its value from conversion as a Collection of this concrete type. But it is being returned as a String[] array. What am I missing?

<h:selectManyMenu value="#{parameter.value}">
    <f:selectItems value="#{parameter.valueList}"/>
</h:selectManyMenu>
public class Parameter<ArrayList<String>> extends ParentClass
{
  private LinkedHashMap<Object, String> valueList;

  public List<SelectItem> getValueList()
  {
    ArrayList<SelectItem> list = new ArrayList<SelectItem>();
    for (Iterator<Object> i = this.valueList.keySet().iterator(); i.hasNext();)
    {
      Object value = i.next();
      list.add(new SelectItem(value, this.valueList.get(value)));
    }

    return list;
  }
}
public abstract class ParentClass<T>
{
  private T value;

  public T getValue() { return this.value; }
  public void setValue(T t) { this.value = t; }
}

Solution

  • I was unable to make JSF read the type definition of the property from the subclass. Specifying the collectionType attribute did not work and even when trying by creating @Override methods in the subclass the backing value being sent to my bean was still a String[] array. The only way I was able to get the JSF servlet to return this value as an ArrayList<String> was to create an additional pair of get/set property methods in the subclass with ArrayList<String> as their return and parameter type.

    public class Parameter extends ParentClass<ArrayList<String>>
    {
      public ArrayList<String> getManyValue() { return super.getValue(); }
      public void setManyValue(ArrayList<String> value) { super.setValue(value); }
    }
    
    
    public abstract class ParentClass<T>
    {
      protected T value;
      public T getValue() { return this.value; }
      public void setValue(T value) { this.value = value; }
    }
    
    
    <h:selectManyMenu value="#{parameter.manyValue}"/>