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?
The generic type information is lost during runtime. All JSF/EL (actually, reflection) sees is a
List
, not aList<Long>
. The default type isString
as that's just the standard return type ofrequest.getParameter()
. This can never returntrue
on aequals()
check on any of theLong
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[]
orLong[]
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 unconvertedString
objects which would in the end only causeClassCastException
when the business code starts to iterate over it.You can use the JSF builtin
javax.faces.Long
converter for this.Update: based on the comments, the
long[]
has most likely caused a conversion error, whileLong[]
works. This is most likely a JSF 1.1 specific bug. Just stick toLong[]
then.