8 Replies Latest reply on Oct 29, 2009 6:00 AM by ilya_shaikovsky

    Initialize controller bean

      Hi everyone,
      I am currently developing a web application using Richfaces 3.3.1 with Spring and Facelets.

      I want to initialize a request scoped controller bean with values later used in a selectonemenu. these values are loaded from database in a init method annotated with @PostConstruct.

      My problem is that although the bean uses the a4j:keepAlive tag the init method is called every time I click a button on the page (and therefore everytime data is loaded from the database). As far as I understood the bean is serialized and the constructor is called on each request. Does that mean that also @PostConstruct is called every time?

      Is this the expected behavior? And if not what is the suggested way to initialize the controller bean when using a4j:keepAlive?

      Best Regards
      Carsten

        • 1. Re: Initialize controller bean

          Hi,
          I just did a few test. The page contains a rich:extendedDataTable component with a binding. If I remove the binding the @PostContruct method is called only once. With the binding the @PostContruct method is called on each request. Is this a bug?

          • 2. Re: Initialize controller bean

            Actually if the page contains ANY component binding then the method is called on each request. Any suggestions how to solve this problem?

            • 3. Re: Initialize controller bean
              nbelaevski

              Can you please add

              Thread.dumpStack();
              to init method and post dumped stack trace here?


              • 4. Re: Initialize controller bean

                This is the call to the init method when opening the page:

                Stack trace
                 at java.lang.Thread.dumpStack(Unknown Source)
                 at controller.admin.TestPage.init(TestPage.java:61)
                 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                 at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
                 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
                 at java.lang.reflect.Method.invoke(Unknown Source)
                 at org.apache.catalina.util.DefaultAnnotationProcessor.postConstruct(DefaultAnnotationProcessor.java:96)
                 at com.sun.faces.vendor.Tomcat6InjectionProvider.invokePostConstruct(Tomcat6InjectionProvider.java:118)
                 at com.sun.faces.mgbean.BeanBuilder.invokePostConstruct(BeanBuilder.java:220)
                 at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:108)
                 at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:368)
                 at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:230)
                 at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:86)
                 at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54)
                 at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
                 at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:61)
                 at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
                 at com.sun.faces.application.ValueBindingValueExpressionAdapter.getValue(ValueBindingValueExpressionAdapter.java:113)
                 at org.ajax4jsf.taglib.html.facelets.KeepAliveHandler.apply(KeepAliveHandler.java:76)
                 at com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47)
                 at com.sun.facelets.tag.ui.DefineHandler.applyDefinition(DefineHandler.java:64)
                 at com.sun.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:131)
                 at com.sun.facelets.impl.DefaultFaceletContext$TemplateManager.apply(DefaultFaceletContext.java:310)
                 at com.sun.facelets.impl.DefaultFaceletContext.includeDefinition(DefaultFaceletContext.java:280)
                 at com.sun.facelets.tag.ui.InsertHandler.apply(InsertHandler.java:68)
                 at com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47)
                 at com.sun.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:49)
                 at com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47)
                 at com.sun.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:25)
                 at com.sun.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:248)
                 at com.sun.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:294)
                 at com.sun.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:273)
                 at com.sun.facelets.impl.DefaultFaceletContext.includeFacelet(DefaultFaceletContext.java:144)
                 at com.sun.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:113)
                 at com.sun.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:49)
                 at com.sun.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:25)
                 at com.sun.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:248)
                 at com.sun.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:294)
                 at com.sun.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:273)
                 at com.sun.facelets.impl.DefaultFaceletContext.includeFacelet(DefaultFaceletContext.java:144)
                 at com.sun.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:113)
                 at com.sun.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:49)
                 at com.sun.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:25)
                 at com.sun.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:95)
                 at com.sun.facelets.FaceletViewHandler.buildView(FaceletViewHandler.java:524)
                 at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:567)
                 at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:100)
                 at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:176)
                 at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110)
                 at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
                 at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
                 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)
                 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
                 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                 at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
                 at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
                 at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:368)
                 at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:495)
                 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
                 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:128)
                 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:293)
                 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
                 at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
                 at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
                 at java.lang.Thread.run(Unknown Source)


                And this is the stack trace when I clicked on the button:

                Stack trace
                 at java.lang.Thread.dumpStack(Unknown Source)
                 at controller.admin.TestPage.init(TestPage.java:61)
                 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                 at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
                 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
                 at java.lang.reflect.Method.invoke(Unknown Source)
                 at org.apache.catalina.util.DefaultAnnotationProcessor.postConstruct(DefaultAnnotationProcessor.java:96)
                 at com.sun.faces.vendor.Tomcat6InjectionProvider.invokePostConstruct(Tomcat6InjectionProvider.java:118)
                 at com.sun.faces.mgbean.BeanBuilder.invokePostConstruct(BeanBuilder.java:220)
                 at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:108)
                 at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:368)
                 at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:230)
                 at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:86)
                 at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54)
                 at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
                 at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:61)
                 at org.apache.el.parser.AstValue.getTarget(AstValue.java:63)
                 at org.apache.el.parser.AstValue.setValue(AstValue.java:133)
                 at org.apache.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:249)
                 at com.sun.facelets.el.TagValueExpression.setValue(TagValueExpression.java:93)
                 at com.sun.faces.lifecycle.RestoreViewPhase.doPerComponentActions(RestoreViewPhase.java:238)
                 at com.sun.faces.lifecycle.RestoreViewPhase.doPerComponentActions(RestoreViewPhase.java:243)
                 at com.sun.faces.lifecycle.RestoreViewPhase.doPerComponentActions(RestoreViewPhase.java:243)
                 at com.sun.faces.lifecycle.RestoreViewPhase.doPerComponentActions(RestoreViewPhase.java:243)
                 at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:198)
                 at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
                 at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:102)
                 at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
                 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
                 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
                 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                 at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
                 at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
                 at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:368)
                 at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:495)
                 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
                 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:128)
                 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:293)
                 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
                 at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
                 at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
                 at java.lang.Thread.run(Unknown Source)


                • 5. Re: Initialize controller bean

                  I hve build a simple page to reproduce the behavior:

                  <!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://java.sun.com/jsf/facelets"
                   xmlns:f="http://java.sun.com/jsf/core"
                   xmlns:h="http://java.sun.com/jsf/html"
                   xmlns:a4j="http://richfaces.org/a4j"
                   xmlns:rich="http://richfaces.org/rich">
                  <head>
                  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
                  </head>
                  <body>
                   <a4j:keepAlive beanName="testPage"/>
                  
                   <a4j:form>
                   <h:inputText id="input1"
                   value="#{testPage.test}"
                   binding="#{testPage.pageComponents.input1}" />
                  
                   <a4j:commandButton value="Update" reRender="input1"
                   actionListener="#{testPage.update}"/>
                   </a4j:form>
                  </body>
                  </html>


                  With the binding each click on update button invokes constructor, init and then update method. Without the binding only update is invoked.

                  • 6. Re: Initialize controller bean
                    nbelaevski

                    This happens because "binding" is evaluated before a4j:keepAlive, so new instance of bean is being created. I see the only solution - do not use binding for keep-alived beans.

                    • 7. Re: Initialize controller bean

                      Ok. Thanx for your help.

                      So as far as I understand the expected behavior of a4j:keepAlive is that the bean instance exists until I leave the view or remove it programmatically (and the constructor is therefore only called once on page initialization)?

                      • 8. Re: Initialize controller bean
                        ilya_shaikovsky

                        yes, it's expected behavior. But it still not restored when binding tries to resolve the bean so it's created before as Nick said. We described this limitation a few time there. But seems it's still undocumented. So I will create a wiki for that.

                        https://jira.jboss.org/jira/browse/RFPL-214

                        Thanks!