[英]Adding filterBy to p:dataTable causes java.lang.NullPointerException at javax.faces.component.StateHolderSaver.<init> on postback
I'm trying to develop a datatable with lazy loading. 我正在尝试开发具有延迟加载的数据表。 Unfiltered and filtered records are correctly loaded from the persistence context through the use of UserService (ie a simple DAO). 通过使用UserService(即简单的DAO),可以从持久性上下文正确加载未过滤和已过滤的记录。 I'm 100% sure the problem is not related to the DAO being used because it has been successfully tested and deployed in other packages. 我100%肯定该问题与所使用的DAO无关,因为它已经成功测试并部署在其他软件包中。
The error comes out when I try to insert a filter: the collection of filtered items is correctly loaded on the page but it looks like at the end of the process something goes wrong and a NPE is thrown. 当我尝试插入过滤器时出现错误:已过滤项目的集合已正确加载到页面上,但看起来在过程结束时出现了问题,并引发了NPE。 After that, the table no longer responds to any command. 此后,该表不再响应任何命令。
Thanks for any help! 谢谢你的帮助!
In the following, the configuration, the view and the controller being used. 以下是配置,视图和所使用的控制器。
Configuration 组态
View (XHTML page) 查看(XHTML页面)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui">
<ui:composition template="/template/template.xhtml">
<ui:define name="body">
<h:form id="UserListForm">
<p:panel header="#{bundle.ListUserTitle}">
<p:dataTable id="UserTable" value="#{userController.users}" var="user" lazy="true" rows="25"
paginator="true" rowKey="#{user.id}" selectionMode="single" selection="#{userController.selected}"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" >
<p:column headerText="#{bundle.User_id}" filterBy="#{user.id}">
<h:outputText value="#{user.id}"/>
</p:column>
<p:column headerText="#{bundle.User_nickname}" filterBy="#{user.nickname}">
<h:outputText value="#{user.nickname}"/>
</p:column>
</p:dataTable>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
</html>
Controller 控制者
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
@Named("userController")
@SessionScoped
@Transactional(Transactional.TxType.REQUIRED)
public class UserController implements Serializable {
@Inject
private UserService userService;
private LazyUserDataModel users;
private User selected;
@PostConstruct
public void init() {
users = new LazyUserDataModel(userService);
}
public User getSelected() {
return selected;
}
public void setSelected(User selected) {
this.selected = selected;
}
public LazyUserDataModel getUsers() {
return users;
}
public void setUsers(LazyUserDataModel users) {
this.users = users;
}
}
Lazy Data Model 懒数据模型
import java.util.List;
import java.util.Map;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
public class LazyUserDataModel extends LazyDataModel<User> {
private List<User> data;
private final UserService userService;
public LazyUserDataModel(UserService userService) {
this.userService = userService;
}
@Override
public User getRowData(String rowKey) {
Long id = Long.valueOf(rowKey);
for (User u : data) {
if (u.getId().equals(id))
return u;
}
return null;
}
@Override
public Object getRowKey(User u) {
return u.getId();
}
@Override
public List<User> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters) {
UserFilterCorrector.correct(filters);
UserFilter filter = new UserFilter(filters, first, pageSize);
FilteredDataModel<User> userDataModel = userService.findFilteredList(filter);
data = userDataModel.getData();
this.setRowCount(userDataModel.getCount().intValue());
return data;
}
}
Exception 例外
11:07:46,348 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (default task-97) Error Rendering View[/user/List.xhtml]: java.lang.NullPointerException
at javax.faces.component.StateHolderSaver.<init>(StateHolderSaver.java:96) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.UIComponentBase.saveAttachedState(UIComponentBase.java:1746) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.ComponentStateHelper.saveMap(ComponentStateHelper.java:378) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.ComponentStateHelper.saveState(ComponentStateHelper.java:256) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.UIComponentBase.saveState(UIComponentBase.java:1552) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.UIData.saveState(UIData.java:1780) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at org.primefaces.component.datatable.DataTable.saveState(DataTable.java:1520) [primefaces-5.1.jar:5.1]
at com.sun.faces.application.view.FaceletPartialStateManagementStrategy$3.visit(FaceletPartialStateManagementStrategy.java:482) [jsf-impl-2.2.8-jbossorg-1.jar:]
at com.sun.faces.component.visit.FullVisitContext.invokeVisitCallback(FullVisitContext.java:151) [jsf-impl-2.2.8-jbossorg-1.jar:]
at org.primefaces.component.api.UIData.visitTree(UIData.java:692) [primefaces-5.1.jar:5.1]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.UIForm.visitTree(UIForm.java:371) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at com.sun.faces.application.view.FaceletPartialStateManagementStrategy.saveView(FaceletPartialStateManagementStrategy.java:472) [jsf-impl-2.2.8-jbossorg-1.jar:]
at com.sun.faces.application.StateManagerImpl.saveView(StateManagerImpl.java:89) [jsf-impl-2.2.8-jbossorg-1.jar:]
at javax.faces.application.StateManager.getViewState(StateManager.java:593) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at com.sun.faces.context.PartialViewContextImpl.renderState(PartialViewContextImpl.java:483) [jsf-impl-2.2.8-jbossorg-1.jar:]
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:325) [jsf-impl-2.2.8-jbossorg-1.jar:]
at org.primefaces.context.PrimePartialViewContext.processPartial(PrimePartialViewContext.java:60) [primefaces-5.1.jar:5.1]
at javax.faces.component.UIViewRoot.encodeChildren(UIViewRoot.java:1004) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:430) [jsf-impl-2.2.8-jbossorg-1.jar:]
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:133) [jsf-impl-2.2.8-jbossorg-1.jar:]
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120) [jsf-impl-2.2.8-jbossorg-1.jar:]
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.2.8-jbossorg-1.jar:]
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219) [jsf-impl-2.2.8-jbossorg-1.jar:]
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:56) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:63) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:261) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:247) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:76) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:166) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:197) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:759) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_25]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_25]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_25]
I solved mine by removing filter value that had null and replacing it with an empty object. 我通过删除具有null的过滤器值并将其替换为空对象来解决了我的问题。 You can put breakpoint in the jsf-api/2.2.8/jsf-api-2.2.8-sources.jar!/javax/faces/component/UIComponentBase.java:1746 and see which value in the filter map is causing the error and then replace it by empty object or remove it. 您可以将断点放在jsf-api / 2.2.8 / jsf-api-2.2.8-sources.jar!/javax/faces/component/UIComponentBase.java:1746中,并查看过滤器映射中哪个值导致了错误然后将其替换为空对象或将其删除。 I hope this helps. 我希望这有帮助。
This must be a bug in the jsf api implementation. 这必须是jsf api实现中的错误。 As you described in your answer @bcavlin there´s not sufficient null-checks in the source code to store a Map that has any key mapped to a null object. 如您在答案@bcavlin中所述,在源代码中没有足够的空检查来存储具有映射到空对象的任何键的Map。 I filed a JIRA issue on this and described it in more dept there, see
JAVASERVERFACES-4088
(old java.net issue) resp. 我对此提交了JIRA问题,并在其中进行了详细说明,请参阅
JAVASERVERFACES-4088
(旧java.net问题)。 JAVASERVERFACES-4092 . JAVASERVERFACES-4092 。
I do it: 我做到了:
Changue code: 变更码:
public StateHolderSaver(FacesContext context, Object toSave){ this.className=toSave.getClass().getName();
to: 至:
public StateHolderSaver(FacesContext context, Object toSave){ this.className=toSave!=null?toSave.getClass().getName():null;
clean and build 清洁和建造
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.