2013-04-27 86 views
0

我有一个数据表,<h:column><h:selectBooleanCheckbox><h:column>的facet标题和DataTable行内容都是<h:selectBooleanCheckbox>。下面是我使用的代码:JSF 1.2:java.util.ConcurrentModificationException

<h:form> 
    <h:dataTable 
     value="#{employeeService.employeeList }" 
     var="empl" 
     binding="#{employeeService.dataTablebinding }"> 
     ...... 
     ...... 
     ...... 
     <h:column> 
      <f:facet name="header">    
       <h:selectBooleanCheckbox id="chkBoxAll" value="#{empl.checked }" valueChangeListener="#{employeeService.checkAll }" onclick="submit()"></h:selectBooleanCheckbox> 
      </f:facet> 
      <h:selectBooleanCheckbox id="tableChkBox" value="#{empl.checked }" valueChangeListener="#{employeeService.getCheckChanged }" onclick="submit()"></h:selectBooleanCheckbox> 
     </h:column> 
    </h:dataTable> 
</h:form> 

当我点击小头复选框,我要检查所有的行复选框,并同为未选中也。这是我对那个小头复选框的ValueChangeListener代码:

public void checkAll(ValueChangeEvent event){  
    for(Employee empl : employeeList){ 
     employeeList.remove(empl); 
     empl.setChecked(true); 
     employeeList.add(empl); 
    }    
} 

我收到以下excception:

SEVERE: AbortProcessingException thrown when processing event of type 'javax.faces.component.WrapperEvent' during phase 'PROCESS_VALIDATIONS 3' for component with ID or Client ID of 'j_id7' 
     27 Apr, 2013 8:20:38 PM javax.faces.component.UIViewRoot broadcastEvents 
     SEVERE: javax.faces.event.AbortProcessingException: java.util.ConcurrentModificationException 
     javax.faces.event.AbortProcessingException: java.util.ConcurrentModificationException 
      at javax.faces.event.MethodExpressionValueChangeListener.processValueChange(MethodExpressionValueChangeListener.java:93) 
      at javax.faces.event.ValueChangeEvent.processListener(ValueChangeEvent.java:134) 
      at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:771) 
      at javax.faces.component.UIData.broadcast(UIData.java:943) 
      at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:444) 
      at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:701) 
      at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76) 
      at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100) 
      at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) 
      at com.icesoft.faces.webapp.http.core.JsfLifecycleExecutor.apply(JsfLifecycleExecutor.java:18) 
      at com.icesoft.faces.webapp.http.core.ReceiveSendUpdates.renderCycle(ReceiveSendUpdates.java:132) 
      at com.icesoft.faces.webapp.http.core.ReceiveSendUpdates.service(ReceiveSendUpdates.java:74) 
      at com.icesoft.faces.webapp.http.core.RequestVerifier.service(RequestVerifier.java:31) 
      at com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer.service(PathDispatcherServer.java:24) 
      at com.icesoft.faces.webapp.http.servlet.BasicAdaptingServlet.service(BasicAdaptingServlet.java:16) 
      at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23) 
      at com.icesoft.faces.webapp.http.servlet.SessionDispatcher.service(SessionDispatcher.java:53) 
      at com.icesoft.faces.webapp.http.servlet.SessionVerifier.service(SessionVerifier.java:26) 
      at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23) 
      at com.icesoft.faces.webapp.http.servlet.MainServlet.service(MainServlet.java:131) 
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
      at com.icesoft.faces.webapp.xmlhttp.BlockingServlet.service(BlockingServlet.java:56) 
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) 
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) 
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) 
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:291) 
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859) 
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602) 
      at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) 
      at java.lang.Thread.run(Thread.java:662) 
     Caused by: java.util.ConcurrentModificationException 
      at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372) 
      at java.util.AbstractList$Itr.next(AbstractList.java:343) 
      at com.infy.service.DataTableService.checkAll(DataTableService.java:66) 
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
      at java.lang.reflect.Method.invoke(Method.java:597) 
      at org.apache.el.parser.AstValue.invoke(AstValue.java:191) 
      at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276) 
      at javax.faces.event.MethodExpressionValueChangeListener.processValueChange(MethodExpressionValueChangeListener.java:91) 
      ... 33 more 

请让我知道这个ConcurrentModificationException的原因。

+0

打开'foreach'环路成'while'回路,并使用迭代器的'删除()'方法来去除'employeeList'的元素。 – Lion 2013-04-27 15:18:45

+0

@Lion你也认为删除元素,修改它并将它放回到**列表**是解决此问题的最佳方法? – 2013-04-27 15:25:54

+0

啊!是的,我没有注意到,对不起。 – Lion 2013-04-27 15:27:45

回答

3
for(Employee empl : employeeList){ 
    empl.setChecked(true); 
    } 

正如Luigi所述,您不需要将该员工从列表中删除。

+0

请用解释来改进答案。 – 2013-04-27 15:11:18

+0

好吧,这解决了异常,但在用户界面中,DataTable的每一行中存在的所有ckeckbox在检查DataTable标题后都没有被检查。如何做到这一点? – user182944 2013-04-27 15:14:03

+1

@ user182944你有两个选择:在检查/取消选择''后使用ajax动作来重新呈现/更新UI,或者在普通的javascript中执行。 – 2013-04-27 15:16:01

3

这是因为当遍历列表要修改它:

for(Employee empl : employeeList){ 
    employeeList.remove(empl); 
    empl.setChecked(true); 
    employeeList.add(empl); 
}    

您需要使用iterator

for(Employee empl : employeeList){ 
    // employeeList.remove(empl); //Not required 
    empl.setChecked(true); 
    //employeeList.add(empl); //Not required 
} 

更新正如Luiggi门多萨提到的,你不需要删除和添加的元素返回列表来改变它。只需参考并修改它。

+1

您甚至不需要从列表中删除并重新添加对象。 – 2013-04-27 15:08:14

+0

@LuiggiMendoza正确,但'ConcurrentModificationException'是由于列表被迭代器修改,是不是? – Apurv 2013-04-27 15:11:12

+0

是的,你就在那里。但是,提议的解决方案不是。顺便说一下,这个错误甚至与JSF没有关系,是基本的Java编程。 – 2013-04-27 15:11:43

1

这不是关于jsf 1.2的问题。这里的问题是,当你迭代它时你不能修改一个Collection。

我想你会得到相同的行为,这样做:

public void checkAll(ValueChangeEvent event){  
for(Employee empl : employeeList){ 
    empl.setChecked(true); 
}    

}

+0

是的,我的错误,因此他们建议我使用迭代器来解决这个问题 – user182944 2013-04-27 15:16:21