title: JSF State saving and custom components with dynamically added children
body: <p>I am developing a JSF custom component. This component has the purpose of encapsulating another component (namely a PrimeFaces table) and adding customized behaviour to it. For example, one of the features that it supports is creating PrimeFaces columns dynamically from the underlying data or from certain attributes. Furthermore, it supports declaring additional PrimeFaces columns in XHTML, which should be added to the encapsulated PrimeFaces table as well.</p>
  
  <p>Consider this example:
  </p>
  
  <pre><code>&lt;my:table id="table" fields="title,label,value,additional"&gt;
      &lt;primefaces:column id="additional"&gt;
          some content
      &lt;/primefaces:column&gt;
  &lt;/my:table&gt;
  </code></pre>
  
  <p>My custom component dynamically creates the PrimeFaces columns from the <code>fields</code> attribute during rendering. It then moves all its <code>column</code> children to the PrimeFaces table, so after rendering the component tree looks like follows:</p>
  
  <pre><code>my:table id="table"
  |---primefaces:table id="table_table"
      |---primefaces:column id="title"
      |---primefaces:column id="label"
      |---primefaces:column id="value"
      |---primefaces:column id="additional"
  </code></pre>
  
  <p>During first rendering, this works fine. However, when I then perform an AJAX update of my component, I get the following exception:</p>
  
  <pre><code>javax.faces.FacesException: Cannot remove the same component twice: table:additional
      at com.sun.faces.context.StateContext$DynamicAddRemoveListener.handleAddRemoveWithAutoPrune(StateContext.java:761)
      at com.sun.faces.context.StateContext$DynamicAddRemoveListener.handleRemove(StateContext.java:629)
      at com.sun.faces.context.StateContext$AddRemoveListener.processEvent(StateContext.java:342)
      at com.sun.faces.context.StateContext$DynamicAddRemoveListener.processEvent(StateContext.java:565)
      at javax.faces.event.SystemEvent.processListener(SystemEvent.java:108)
      at javax.faces.event.ComponentSystemEvent.processListener(ComponentSystemEvent.java:118)
      at com.sun.faces.application.ApplicationImpl.processListenersAccountingForAdds(ApplicationImpl.java:2218)
      at com.sun.faces.application.ApplicationImpl.invokeViewListenersFor(ApplicationImpl.java:2036)
      at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:290)
      at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:245)
      at javax.faces.application.ApplicationWrapper.publishEvent(ApplicationWrapper.java:726)
      at javax.faces.component.UIComponentBase.disconnectFromView(UIComponentBase.java:2275)
      at javax.faces.component.UIComponentBase.doPreRemoveProcessing(UIComponentBase.java:1939)
      at javax.faces.component.UIComponentBase.setParent(UIComponentBase.java:437)
      at javax.faces.component.UIComponentBase$ChildrenList.remove(UIComponentBase.java:2757)
      at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.adjustIndexOfDynamicChildren(ComponentTagHandlerDelegateImpl.java:283)
      at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:223)
      at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
      at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
      at com.sun.faces.facelets.tag.ui.DefineHandler.applyDefinition(DefineHandler.java:106)
      at com.sun.faces.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:206)
      at com.sun.faces.facelets.impl.DefaultFaceletContext$TemplateManager.apply(DefaultFaceletContext.java:395)
      at com.sun.faces.facelets.impl.DefaultFaceletContext.includeDefinition(DefaultFaceletContext.java:366)
      at com.sun.faces.facelets.tag.ui.InsertHandler.apply(InsertHandler.java:111)
      at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
      at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:202)
      at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
      at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
      at com.sun.faces.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:194)
      at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
      at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:87)
      at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:312)
      at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:371)
      at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:350)
      at com.sun.faces.facelets.impl.DefaultFaceletContext.includeFacelet(DefaultFaceletContext.java:199)
      at com.sun.faces.facelets.tag.ui.IncludeHandler.apply(IncludeHandler.java:124)
      at com.sun.faces.facelets.tag.ui.InsertHandler.apply(InsertHandler.java:116)
      at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
      at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
      at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:202)
      at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
      at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
      at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
      at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:202)
      at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
      at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
      at com.sun.faces.facelets.tag.ui.DefineHandler.applyDefinition(DefineHandler.java:106)
      at com.sun.faces.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:206)
      at com.sun.faces.facelets.impl.DefaultFaceletContext$TemplateManager.apply(DefaultFaceletContext.java:395)
      at com.sun.faces.facelets.impl.DefaultFaceletContext.includeDefinition(DefaultFaceletContext.java:366)
      at com.sun.faces.facelets.tag.ui.InsertHandler.apply(InsertHandler.java:111)
      at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
      at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
      at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:202)
      at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
      at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
      at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
      at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:202)
      at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
      at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
      at com.sun.faces.facelets.tag.jsf.core.ViewHandler.apply(ViewHandler.java:225)
      at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
      at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
      at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:202)
      at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
      at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
      at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
      at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:87)
      at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:312)
      at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:371)
      at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:350)
      at com.sun.faces.facelets.impl.DefaultFaceletContext.includeFacelet(DefaultFaceletContext.java:199)
      at com.sun.faces.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:174)
      at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
      at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:87)
      at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:312)
      at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:371)
      at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:350)
      at com.sun.faces.facelets.impl.DefaultFaceletContext.includeFacelet(DefaultFaceletContext.java:199)
      at com.sun.faces.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:174)
      at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
      at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:87)
      at com.sun.faces.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:161)
      at com.sun.faces.application.view.FaceletViewHandlingStrategy.buildView(FaceletViewHandlingStrategy.java:1006)
      at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:99)
      at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
      at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
      at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
      at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
      at de.gebit.trend.servlet.security.AuthorizationFilter.doFilter(AuthorizationFilter.java:269)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
      at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
      at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
      at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
      at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:789)
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
      at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Unknown Source)
  </code></pre>
  
  <p>So, only the <code>column</code> that was moved from my table to the PrimeFaces table is creating this error. The other columns do not get recreated, because during rendering, I use an instance variable stored in the <code>StateHelper</code> to indicate that columns are already created.</p>
  
  <p>I somehow understand where this exception is coming from and that it has something to do with JSF saving the complete component tree, and when JSF restores the view, the saved state is inconsistent with the XHTML. What I don't know is, how to solve this problem. </p>
  
  <p>Could someone please explain to me how this state saving mechanism exactly works, especially in conjunction with dynamically added children and how to avoid this exception?</p>
  
  <h1>UPDATE (10.02.2017)</h1>
  
  <p>I've created a small sample project without additional frameworks that were in use before. It can be found on my <a href="https://github.com/jessepeng/jsf-dynamic-children-test" rel="nofollow noreferrer">GitHub profile</a>. One main framework that was in use before was fiddeling with the <code>AddRemoveListeners</code> installed in the <code>StateContext</code> for replaying dynamic actions. To avoid this having an impact on my issue and to create a reproducible environment, I removed them.</p>
  
  <p>The behavior I witness now is slightly different (there are no exceptions anymore) and depends on whether <strong>partial state saving</strong> is enabled/disabled and the method I use to move the <code>primefaces:column</code>:</p>
  
  <p>The first rendering of the table in all cases works fine. I then perform a postback request by submitting a paging request. The behavior then is erronous in some cases.</p>
  
  <h2>Partial state saving enabled</h2>
  
  <p>With partial state saving enabled, paging does not work. I do not get an exception, but a lot of warnings similar to this:</p>
  
  <pre><code>Feb 10, 2017 4:33:11 PM com.sun.faces.application.view.FaceletPartialStateManagementStrategy saveDynamicActions
  WARNUNG: Unable to save dynamic action with clientId 'form:table:table_table:additional' because the UIComponent cannot be found
  </code></pre>
  
  <p>This warning appears for every component that was moved dynamically created in or moved to the <code>primefaces:table</code> or was a child component of one of those.</p>
  
  <h2>Partial state saving disabled</h2>
  
  <p>With partial state saving disabled, paging does work but shows different behavior depending on when the one custom <code>primefaces:column</code> is moved.</p>
  
  <h3>Moving of `column` during render response phase</h3>
  
  <p>When the <code>primefaces:column</code> is moved during render response phase, e.g. in <code>encodeXxx</code>, everything works fine. All the columns are in the correct order and with correct values and paging works perfectly fine.</p>
  
  <h3>Moving of `column` using a `PostAddToViewEvent`</h3>
  
  <p>When using this approach, as per <strong>@BalusC</strong> suggestion, the moved <code>primefaces:column</code> disappears on paging. The <code>PostAddToViewEvent</code> is called several times and the <code>column</code> is moved while handling this event, however on rendering, it has disappeared and only the three previously created <code>column</code>s are still there.</p>
  
  <p>At this point, I am more than confused. Is this a bug in Mojarra or in Primefaces or am I doing something wrong? Is this kind of behavior even possible with JSF?</p>