views:

6009

answers:

1

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?

+4  A: 

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:

An EL expression that specifies the data model that backs this table.

The value referenced by the EL expression can be of any type.

    * A value of type DataModel is used directly.
    * Array-like parameters of type array-of-Object, java.util.List, 
java.sql.ResultSet or javax.servlet.jsp.jstl.sql.Result are wrapped 
in a corresponding DataModel that knows how to iterate over the elements.
    * Other values are wrapped in a DataModel as a single row.

Note in particular that unordered collections, eg Set are not supported. 
Therefore if the value expression references such an object then the 
table will be considered to contain just one element - the collection itself.

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.

Bill James