I’m using JSF/Facelets, and I’m trying to iterate over some Document objects (custom object) that I’m keeping in a HashMap. When the page is loaded, I’m getting the error ‘Property ‘name’ not found on type java.util.HashMap$Values’. Here’s what’s in my backing bean:
private Map<String, Document> documents = new HashMap<String, Document>(); public Collection<Document> getDocuments(){ return documents.values(); }
And in my xhtml page:
<h:dataTable id='documentTable' value='#{DocumentManager.allDocuments}' var='doc' rowClasses='list-row-odd, list-row-even' headerClass='table-header' styleClass='bordered'> <h:column id='col_name'> <f:facet name='header'>Name</f:facet> ${doc.name} </h:column> </h:dataTable>
If I change the getDocuments function to the following, it works (meaning the table is displayed without error), but I’m not sure why I need to put the values in the list for the JSF/Facelets page to display properly.
public List<Document> getDocuments(){ List<Document> rtrn = new ArrayList<Document>(); for(Document doc : documents.values()) rtrn.add(doc); return rtrn; }
Shouldn’t I be able to iterate over the Collection?
Well, as it turns out, you can’t just use any kind of collection type with dataTable, and for good reason. From the MyFaces 1.2 Spec, the value attribute must be:
The Collection returned from HashSet.values() is not ordered and, therefore is not supported. If it was, you’d have no idea what order the rows in your table would be output, and refreshes of the page could re-order them randomly. Not good.
The error you’re getting is, from the last paragraph, it says that the datatable is treating your Collection as the row object, and Collection doesn’t have a ‘name’ property.