I'm writing a JSF application which lets the user select a list of documents from a list of folders where the user clicks the specific folder link to see the list of documents related to the selected folder. The folder list is displayed from the following XHTML page:
<p:dataTable value="#{projectDocsFolderBean.listModel}" var="docs">
<p:column headerText="Folders:">
<h:commandLink action="#{projectDocBean.selectFolderDocs}"
value="#{docs.classification}" />
</p:column>
</p:dataTable>
Where the classification field is supposed to display a list of folder names but gives this stack:
WARNING: StandardWrapperValve[Faces Servlet]: Servlet.service() for servlet Faces Servlet threw exception
java.lang.NumberFormatException: For input string: "classification"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.parseInt(Integer.java:527)
at javax.el.ArrayELResolver.toInteger(ArrayELResolver.java:378)
at javax.el.ArrayELResolver.getValue(ArrayELResolver.java:198)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)....
I'm almost sure that this is caused by the use of explicit Select statements in my DAO class (where I'm selecting specific entity fields instead of the whole entiy), so that the results are returned as an array. If I try to call docs[0] in the JSF data table, the list displays fine, but I want to be able to explicitly call docs.classification instead of using array indices.
The below question does not adequately answer MY question because I do not want to use array indices but rather explicit EL properties (ie: docs.classification NOT docs[0]). In this case, I would like to know 1) What the appropriate result class should look like (see my below attempt)? 2) Do I need to include a custom conversion class in addition or instead of the defined result class?
The above is helpful but I already understand that the structure of my query returns a tuple and my question as above is if there is a way to get around that without having to use array indices.
After trying conventional ORM methods, I tried to define the following result class:
@SuppressWarnings("unchecked")
public List<ProjectDocs> findAllFolders(int projectid) {
final String SQLCOMMAND
= "SELECT DISTINCT d.classification, d.fk_projectdoc_id " + "FROM "
+ ProjectDocs.class.getSimpleName() + " d "
+ " WHERE d.fk_projectdoc_id = ?1";
Query query = em.createQuery(SQLCOMMAND);
query.setParameter(1, projectid);
try {
// ListDataModel<ProjectDocs> lresults = new ListDataModel<ProjectDocs>(query.getResultList());
List<ProjectDocs> lresults = query.getResultList();
return lresults;
} catch (Exception ex) {
throw new RuntimeException("FAILED", ex);
}
}
And the JSF Managed bean class is as follows (I also tried using a CDI bean but this product a NPE):
@ManagedProperty(value = "#{projBB}")
// @Model
private ProjectsBB projectBean;
public String selectFolders() {
projects = projectBean.getProjectList().getRowData();
projectid = projects.getProjectid();
projects.setProjectid(projectid);
listModel = (ListDataModel<ProjectDocs>) getFolderBaseModel();
return "ProDocsFolderList";
}
public DataModel<ProjectDocs> getFolderBaseModel() {
/* Check cache */
if (this.folderBaseModel == null) {
this.folderBaseModel= buildFolderListModel(this.projectid);
}
return this.folderBaseModel;
}
public DataModel<ProjectDocs> buildFolderListModel(int projectid) {
List<ProjectDocs> folderList = proDocs.findFolderList(projectid);
DataModel<ProjectDocs> model = new ListDataModel<ProjectDocs>(folderList);
return model;
}
Thank you!