ExtendedDataTable Bug?
larsd Oct 5, 2011 12:23 PMHello,
I'm developing an component within a extendedDataTable an get a strange NullPointerException from Richfaces.
The solution with the PageabledDataModel etc. works fine on other pages. I want to simplify the solution and created a component, which produces this Exception while rendering the first row only if I'm not calling findObjects directly.
xhtml code:
<composite:implementation>
<corr:corOverviewBtnGroup
resetFilterBtnID="#{cc.attrs.resetFilterBtnID}"
crudBean="#{cc.attrs.crudBean}"
filterBean="#{cc.attrs.filterBean}"
doSearchBtnID="#{cc.attrs.doSearchBtnID}"
createBtnID="#{cc.attrs.createBtnID}"
createPopUpPanelGroupID="#{cc.attrs.createPopUpPanelGroupID}">
</corr:corOverviewBtnGroup>
<hr />
<rich:extendedDataTable
id="#{cc.attrs.tableId}"
value="#{cc.attrs.tableDataModel}"
(does produce the exception, but findObjects is called (debugging) and delivers the right list of entities), Exception is throw while rendering the first row
value="#{cc.attrs.tableDataModel.findObjects(0,100)}"
(does work)
var="entity"
frozenColumns="1"
rows="#{cc.attrs.tableRows}"
style="width: 100%;">
<rich:column>
<f:facet name="header">
<div align="center">
<h:outputText value="#{commonTrans.corOverviewTableComponentActionColumn}" />
</div>
</f:facet>
<div align="center">
<a4j:commandLink
id="cl_deleteIcon#{cc.attrs.tableId}"
styleClass="no-decor"
immediate="true"
execute="@this"
action="#{cc.attrs.crudBean.startDelete(entity)}"
render=":#{cc.attrs.deletePopUpPanelGroupID}"
rendered="#{cc.attrs.actionPermission}">
<h:graphicImage
id="img_deleteIcon#{cc.attrs.tableId}"
value="/images/tables/row_delete.gif"
alt="delete"
width="11"
height="11" />
</a4j:commandLink>
<a4j:commandLink
id="cl_editIcon#{cc.attrs.tableId}"
styleClass="no-decor"
immediate="true"
execute="@this"
action="#{cc.attrs.crudBean.startEdit(entity)}"
render=":#{cc.attrs.editPopUpPanelGroupID}"
rendered="#{cc.attrs.actionPermission}">
<h:graphicImage
id="img_editIcon#{cc.attrs.tableId}"
value="/images/tables/row_edit.gif"
alt="edit"
width="11"
height="11" />
</a4j:commandLink>
</div>
</rich:column>
<c:forEach
items="#{cc.attrs.tableListOfColumns}"
var="column">
<rich:column width="#{column.width}px" rendered="true">
<f:facet name="header">
<div align="center">
<comp:sortColumnHeader
headerLabel="#{column.headerLabel}"
sortField="#{column.sortField}"
currentDataModel="#{cc.attrs.tableDataModel}"
render="#{cc.attrs.tableId}" />
<br />
<h:inputText rendered="#{not column.dateField}">
<a4j:ajax
event="keyup"
render="#{cc.attrs.tableId}@body"
execute="@form" />
</h:inputText>
<rich:calendar
rendered="#{column.dateField}"
id="cal_#{column.attributeName}DatePicker"
onmousedown="event.stopPropagation()" datePattern="#{lov:getDatePattern('SHORT_DATE')}">
</rich:calendar>
</div>
</f:facet>
<div align="center">
<comp:tableText text="#{cc.attrs.tableDataModel.getCurrentColumnValue(entity, column)}" />
</div>
</rich:column>
</c:forEach>
<f:facet name="footer">
<rich:dataScroller
id="ds_#{cc.attrs.tableId}"
for="#{cc.attrs.tableId}"
maxPages="10"
render="#{cc.attrs.tableId}">
</rich:dataScroller>
</f:facet>
</rich:extendedDataTable>
</composite:implementation>
Beans:
public class MyDataModel extends PageableDataModel<Group, Long> implements
MyDatamodelInterface<Group> {
...
@Override
public List<Group> findObjects(int firstRow, int numberOfRows) {
MyDTO groupQueryDTO = new MyDTO();
groupQueryDTO.setStartFrom(firstRow);
groupQueryDTO.setAmount(numberOfRows);
final Map.Entry<String, String> search = getSortFieldOrder();
if (search != null && !StringUtils.isEmpty(search.getKey())
&& !QueryDTO.SORT_UNDEFINED.equals(search.getValue())) {
groupQueryDTO.setSortColumn(search.getKey());
groupQueryDTO.setSortDirection(search.getValue());
}
ListModelDTO<Group> groups =
getGroupAdminService().findGroups(RequestContextStack.getRequestContext(), groupQueryDTO);
resultCount = groups.getCount().intValue();
return groups.getCurrentPayload();
}
@Override
public int getNumRecords() {
return resultCount;
}
@Override
public Group getObjectById(Long identifier) {
return currentGroups.get(identifier);
}
@Override
public Long getId(Group object) {
return object.getId();
}
...
}
public abstract class PageableDataModel<T extends Serializable, U extends Serializable> extends ExtendedDataModel
implements Serializable {
... (works fine in other cases)
}
Exception:
java.lang.NullPointerException
org.richfaces.renderkit.ExtendedDataTableRenderer.encodeRow(ExtendedDataTableRenderer.java:783)
org.richfaces.renderkit.AbstractRowsRenderer.process(AbstractRowsRenderer.java:89)
com.lpsolutions.gui.common.model.PageableDataModel.walk(PageableDataModel.java:203)
org.richfaces.component.UIDataAdaptor.walk(UIDataAdaptor.java:810)
org.richfaces.renderkit.AbstractRowsRenderer.encodeRows(AbstractRowsRenderer.java:99)
org.richfaces.renderkit.ExtendedDataTableRenderer.encodeBody(ExtendedDataTableRenderer.java:438)
org.richfaces.renderkit.ExtendedDataTableRenderer.doEncodeChildren(ExtendedDataTableRenderer.java:642)
org.richfaces.renderkit.RendererBase.encodeChildren(RendererBase.java:157)
javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:848)
com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:287)
com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:106)
javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:848)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1613)
com.sun.faces.renderkit.html_basic.CompositeRenderer.encodeChildren(CompositeRenderer.java:75)
javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:848)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1613)
javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:848)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1613)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:380)
com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:126)
javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:273)
javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:273)
javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:273)
javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:273)
org.apache.myfaces.tomahawk.application.ResourceViewHandlerWrapper.renderView(ResourceViewHandlerWrapper.java:93)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:127)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
org.apache.myfaces.extensions.cdi.jsf2.impl.listener.phase.CodiLifecycleWrapper.render(CodiLifecycleWrapper.java:122)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
com.lpsolutions.gui.common.listener.RequestContextSetupFilter.doFilter(RequestContextSetupFilter.java:64)
com.lpsolutions.gui.common.listener.SessionInvalidationFilter.doFilter(SessionInvalidationFilter.java:44)
org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:349)
Thanks in advance.
Lars