You're right. I use it inside datatable.
Then this can happen if #{bean} represents the current iterated object declared in the var attribute as follows:
<h:dataTable value="#{someBean.beans}" var="bean"> <h:column> <h:outputText id="#{bean.id}" value="#{bean.value}" />
The id (and binding ) attribute of the JSF component is evaluated during build time, at the moment the JSF component tree is to be compiled. However, #{bean} is available only during time rendering, at a time when <h:dataTable> needs to <h:dataTable> over all objects and generate HTML table rows for each of them. Thus, #{bean} unavailable during build time and evaluates to null , which ultimately gets the forced EL value to an empty string. And therefore the java.lang.IllegalArgumentException: Empty id attribute is not allowed exception java.lang.IllegalArgumentException: Empty id attribute is not allowed .
You have basically 3 options:
Instead, use the view build time tag to iterate over the collection. You just need to write the whole HTML template:
<table> <c:forEach items="#{someBean.beans}" var="bean"> <tr> <td> <h:outputText id="#{bean.id}" value="#{bean.value}" />
Use a simple HTML element:
<h:dataTable value="#{someBean.beans}" var="bean"> <h:column> <span id="#{bean.id}">#{bean.value}</span>
Do not set a dynamic identifier, but a fixed identifier. JSF will ensure the uniqueness of HTML output by adding it with the table row index:
<h:dataTable value="#{someBean.beans}" var="bean"> <h:column> <h:outputText id="id" value="#{bean.value}" />
See also:
source share