JSF 1.1: selectManyCheckbox not submitting properly

1.1k views Asked by At

I have a problem with the selectManyCheckbox tag..

We are using JSF 1.1 inside a JBoss Portal (i think its version 4.2, but not sure)..

I have the following JSF markup:

<h:selectManyCheckbox layout="lineDirection" 
   value="#{personBean.selectedPersonsLongArray}"
   id="selectedPersons">
   <f:selectItems value="#{personBean.persons}" />
</h:selectManyCheckbox>

(And of course I have a button that submits the form). My bean looks like this:

    public class PersonBean {
        private List<SelectItem> persons;

        private List<SelectItem> selectedPersons = new ArrayList<SelectItem>(); // +getter +setter
        private List<String> selectedPersonsStringList = new ArrayList<String>();// +getter +setter
        private List<Long> selectedPersonsStringList = new ArrayList<Long>();// +getter +setter
        private long[] selectedPersonsLongArray = new long[0];// +getter +setter
        private String[] selectedPersonsStringArray = new String[0]; // +getter +setter

        public void getPersons(){
            if(persons == null){
                List<Person> personsFromDb = // get from DB
                persons = new ArrayList<Person>(personsFromDb.size());
                for(Person person : personsFromDb){
                    // ID of a person is a long
                    persons.add(new SelectItem(person.getId(), person.getName()));
                }
            }
            return persons;
        }

        public void setPersons(List<SelectItem> persons){
            this.persons = persons;
        }

        ...
    }

The bean is session scoped and Person's Id property is of type long. I have tried binding the value of the tag to all the types listed in the bean. On submit, all but selectedPersonLongArray gives a "Validation Error" message. If I bind it to selectedPersonLongArray i get an error saying selectedPersons must be filled out.

As I said, the bean is session scoped, and I have double-checked that the persons list does not change between requests, which seems to be a common problem with this tag.

Any ideas?

1

There are 1 answers

10
BalusC On BEST ANSWER

The generic type information is lost during runtime. All JSF/EL (actually, reflection) sees is a List, not a List<Long>. The default type is String as that's just the standard return type of request.getParameter(). This can never return true on a equals() check on any of the Long values in the list of available items. That explains the "Validation Error: Value is not valid" error.

You need a fixed type property such as long[] or Long[] so that JSF/EL will be able to determine the right type by reflection.

If you really need it to be a List<Long> due to design restrictions, then you should explicitly specify a converter. Otherwise JSF will just fill it with unconverted String objects which would in the end only cause ClassCastException when the business code starts to iterate over it.

You can use the JSF builtin javax.faces.Long converter for this.

<h:selectManyCheckbox ... converter="javax.faces.Long">

Update: based on the comments, the long[] has most likely caused a conversion error, while Long[] works. This is most likely a JSF 1.1 specific bug. Just stick to Long[] then.