9 Replies Latest reply on Dec 26, 2007 6:56 PM by asookazian

    resetting/clearing a session scoped SFSB

    asookazian

      I have a conversation scoped SFSB which has a session scoped SFSB injected into it as follows:

      @In(create=true)
      private NoteLocal noteAction;


      In my xhtml, there is a h:selectOneMenu coded as follows:
      <h:form id="peerForm">
       <h:selectOneMenu id="selectPeer" value="#{peerAction.employeeId}">
       <a4j:support event="onchange"
       onchange="changePeer()"/>
       <f:selectItems value="#{peerAction.peers}" />
       </h:selectOneMenu>
       </h:form>


      The javascript function changePeer() does the following:
      function changePeer() {
       Richfaces.showModalPanel('mpChangePeer',{width:450, top:200});
       }


      And the modalPanel is as follows:
       <rich:modalPanel id="mpChangePeer" minHeight="200" minWidth="450"
       height="500" width="500" zindex="2000">
      
       <f:facet name="header">
       <a4j:outputPanel>
       <h:outputText id="mpChangePeerWarning" value="Warning"/>
       </a4j:outputPanel>
       </f:facet>
      
       <a4j:form id="a4jChangePeer">
       <h:outputText value="Are you sure you want to switch to a peer? You will lose all unsaved changes."/>
       <BR/>
       <h:panelGrid columns="2">
       <a4j:commandButton value="Continue"
       action="#{securityAuditAction.findAuditList}"
       onclick="Richfaces.hideModalPanel('mpChangePeer')"
       ajaxSingle="true"
       reRender="mainForm"/>
       <BR/>
       <a4j:commandButton value="Cancel" onclick="Richfaces.hideModalPanel('mpChangePeer')"/>
       </h:panelGrid>
       </a4j:form>
      
       </rich:modalPanel>


      My question is when the user clicks 'Continue' button, I need to reset and/or clear and/or instantiate a new instance of the session scoped SFSB so that the data is fresh/clear and data shows properly in the dataTable of the main form.

      What is the best way to do this in Seam?

      The other question (which I may post on richfaces forum) is that if they click 'Cancel' then I need to reset to h:selectOneMenu value to the previous value. How do I do this? thx.

        • 1. Re: resetting/clearing a session scoped SFSB
          pmuir

          Try contexts.getSessionContext().remove(sfsb);

          But I think the fact you have to do this probably indicates your SFSB is in the wrong scope.

          • 2. Re: resetting/clearing a session scoped SFSB
            asookazian

            hmm. when the user selects another manager in the h:selectOneMenu, it's like they're started another session (similar to logging in as another user).

            the reason the injected NoteAction is session scoped is because it needs to handle all the note data that is entered in the main form dataTable (other SFSB) prior to submission (i.e. user may enter notes for multiple rows/employees prior to saving the first one).

            if the scope of the NoteAction was conversation I would not be able to meet the functional requirement UNLESS I forced the user to enter and save one row at a time by disabling all inactive rows...

            so if this is the case, i don't understand why the context/scope of the two SFSB's is incorrect....

            • 3. Re: resetting/clearing a session scoped SFSB
              pmuir

               

              "asookazian" wrote:
              hmm. when the user selects another manager in the h:selectOneMenu, it's like they're started another session (similar to logging in as another user).


              So, then invalidate the session.

              the reason the injected NoteAction is session scoped is because it needs to handle all the note data that is entered in the main form dataTable (other SFSB) prior to submission (i.e. user may enter notes for multiple rows/employees prior to saving the first one).

              if the scope of the NoteAction was conversation I would not be able to meet the functional requirement UNLESS I forced the user to enter and save one row at a time by disabling all inactive rows...

              so if this is the case, i don't understand why the context/scope of the two SFSB's is incorrect....


              I don't quite see why this means it must be Session scoped, only data/actions which should be used over the time the user has their browser should be session scoped. Anyway, this is application design, which you have to decide on ;)

              • 4. Re: resetting/clearing a session scoped SFSB
                asookazian

                I tried the following code:

                Session.instance().invalidate();


                1) I have 2 session-scoped SFSB's. How does Seam handle this? Are both of them invalidated?

                2) How/when does Seam re-instantiate the SFSB's that were invalidated?

                I am getting the following exception when peerAction SFSB is referenced below:
                Caused by: java.lang.NullPointerException
                 at com.cox.beans.session.SecurityAuditAction.findAuditList(SecurityAuditAction.java:151)
                 at com.cox.beans.session.SecurityAuditAction.invalidateSession(SecurityAuditAction.java:134)


                with:
                public void invalidateSession() {
                
                 //user selected a peer from peer selectOneMenu, so invalidate session and continue...
                
                 Session.instance().invalidate();
                
                 findAuditList();
                 }
                
                 // 12-03/07 - got following exception when I clicked cancel in modalPanel:
                 // Caused by java.lang.IllegalStateException with message: "begin method invoked from a long-running conversation, try using @Begin(join=true) on method: findAuditList"
                 // adding join=true...
                
                 @Begin(join=true, flushMode=FlushModeType.MANUAL) // <-- use this with SMPC
                 @Factory("myAuditList")
                 public void findAuditList()
                 {
                 Boolean hardCodeEmployeeId = Boolean.parseBoolean(SecurityAuditProperties.getPropertyObject().getProperty(SecurityAuditConstants.HARD_CODE_EMPLOYEE_ID));
                 Integer employeeId;
                
                 if (hardCodeEmployeeId) { //if true in props file then we're testing only...
                
                 employeeId = peerAction.getEmployeeId().intValue();
                
                 if (employeeId == null) {
                
                 employeeId = Integer.parseInt(SecurityAuditProperties.getPropertyObject().getProperty(SecurityAuditConstants.EMPLOYEE_ID)); //using btkach id for now;
                 }
                 }
                 else {
                 log.info("in getAuditList(): user.getUserId() = " + user.getUserId() + " user.getBillingId() = " + user.getBillingId());
                
                 //employeeId = getEmployeeId();
                
                 employeeId = peerAction.getEmployeeId().intValue();
                
                 }
                 myAuditList = emICOMS.createQuery("SELECT gem, tsaw "+
                 "FROM TblSecurityAuditWorking tsaw, "+
                 "GlobalEmployeeMaster gem "+
                 "WHERE tsaw.id.siteId = gem.id.siteId "+
                 "AND tsaw.id.employeeNumber = gem.id.employeeNumber "+
                 "AND tsaw.reportToId = :employeeId " +
                 "ORDER BY tsaw.id.employeeNumber ASC")
                 .setParameter("employeeId", employeeId)
                 .getResultList();
                
                 //instantiate null valued noteList
                 noteAction.initialize(myAuditList);
                
                 log.info("in findAuditList(): myAuditList.size() = " + myAuditList.size());
                
                 noteLoadList = emICOMS.createQuery("SELECT saw.id.siteId, saw.id.employeeNumber, "+
                 "("+
                 "SELECT count(san) as AcctApprovedNoteCount "+
                 "FROM TblSecurityAuditNote san "+
                 "WHERE san.siteId = saw.id.siteId "+
                 "AND san.employeeNumber = saw.id.employeeNumber "+
                 "AND san.noteType = 'accountApproved' "+
                 ") as AcctApprovedCount, "+
                 "("+
                 "SELECT count(san) as secLevelApprovedNoteCount "+
                 "FROM TblSecurityAuditNote san "+
                 "WHERE san.siteId = saw.id.siteId "+
                 "AND san.employeeNumber = saw.id.employeeNumber "+
                 "AND san.noteType = 'secLevelApproved' "+
                 ") as secLevelApprovedCount, "+
                 "("+
                 "SELECT count(san) as adjLimitApprovedNoteCount "+
                 "FROM TblSecurityAuditNote san "+
                 "WHERE san.siteId = saw.id.siteId "+
                 "AND san.employeeNumber = saw.id.employeeNumber "+
                 "AND san.noteType = 'adjLimitApproved' "+
                 ") as adjLimitApprovedCount "+
                 "FROM TblSecurityAuditWorking saw "+
                 "WHERE saw.reportToId = :employeeId")
                 .setParameter("employeeId", employeeId)
                 .getResultList();
                
                
                
                 log.info("in findAuditList(): noteLoadList.size() = " + noteLoadList.size());
                
                
                
                 }


                • 5. Re: resetting/clearing a session scoped SFSB
                  asookazian

                  I added @End for the public void invalidateSession() method and get:

                  Caused by javax.ejb.EJBTransactionRolledbackException with message: "No active JTA transaction on joinTransaction call"
                  org.jboss.ejb3.tx.Ejb3TxPolicy.handleInCallerTx(Ejb3TxPolicy.java:87)
                  org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:130)
                  org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:195)
                  org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                  org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
                  org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                  org.jboss.ejb3.stateful.StatefulInstanceInterceptor.invoke(StatefulInstanceInterceptor.java:83)
                  org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                  org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
                  org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:106)
                  org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                  org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
                  org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                  org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
                  org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                  org.jboss.ejb3.stateful.StatefulContainer.localInvoke(StatefulContainer.java:204)
                  org.jboss.ejb3.stateful.StatefulLocalProxy.invoke(StatefulLocalProxy.java:100)
                  $Proxy112.getEmployeeId(Unknown Source)
                  sun.reflect.GeneratedMethodAccessor258.invoke(Unknown Source)
                  sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
                  java.lang.reflect.Method.invoke(Unknown Source)
                  org.jboss.seam.util.Reflections.invoke(Reflections.java:21)
                  org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31)
                  org.jboss.seam.intercept.ClientSideInterceptor$1.proceed(ClientSideInterceptor.java:76)
                  org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
                  org.jboss.seam.ejb.RemoveInterceptor.aroundInvoke(RemoveInterceptor.java:41)
                  org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                  org.jboss.seam.core.SynchronizationInterceptor.aroundInvoke(SynchronizationInterceptor.java:32)
                  org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                  org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:106)
                  org.jboss.seam.intercept.ClientSideInterceptor.invoke(ClientSideInterceptor.java:54)
                  org.javassist.tmp.java.lang.Object_$$_javassist_1.getEmployeeId(Object_$$_javassist_1.java)
                  com.cox.beans.session.SecurityAuditAction.findAuditList(SecurityAuditAction.java:151)
                  


                  also getting following exception (???) when I use a new method as follows:

                  @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
                   private void findAuditList2()


                  14:03:53,202 ERROR [SeamPhaseListener] uncaught exception
                  java.lang.IllegalStateException: missing conversation entry
                   at org.jboss.seam.core.Conversation.flush(Conversation.java:124)
                   at org.jboss.seam.core.Manager.flushConversationMetadata(Manager.java:882)
                   at org.jboss.seam.faces.FacesManager.prepareBackswitch(FacesManager.java:278)
                   at org.jboss.seam.jsf.SeamPhaseListener.afterRenderResponse(SeamPhaseListener.java:487)
                   at org.jboss.seam.jsf.SeamPhaseListener.afterServletPhase(SeamPhaseListener.java:230)
                   at org.jboss.seam.jsf.SeamPhaseListener.afterPhase(SeamPhaseListener.java:184)
                   at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:280)
                   at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:144)
                   at javax.faces.webapp.FacesServlet.service(FacesServlet.java:245)
                   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
                   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                   at jcifs.http.NtlmHttpFilter.doFilter(NtlmHttpFilter.java:118)
                   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
                   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                   at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
                   at org.jboss.seam.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:68)
                   at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                   at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:85)
                   at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                   at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
                   at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                   at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:44)
                   at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                   at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141)
                   at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281)
                   at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:60)
                   at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                   at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
                   at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                   at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
                   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
                   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                   at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
                   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:230)
                   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
                   at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
                   at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
                   at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
                   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
                   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
                   at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
                   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
                   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241)
                   at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
                   at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:580)
                   at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
                   at java.lang.Thread.run(Unknown Source)
                  


                  • 6. Re: resetting/clearing a session scoped SFSB
                    asookazian

                    After the Session.instance().invalidate() call, I am seeing two of the SFSB's that are session-scoped are being destroyed:

                    14:32:51,032 INFO [LoggerInterceptor] *** Entering method: destroy
                    14:32:51,032 INFO [SecurityAuditAction] in preDestroy
                    14:32:51,048 INFO [LoggerInterceptor] *** Entering method: destroy
                    14:32:51,048 INFO [NoteAction] in preDestroy
                    14:32:51,064 INFO [LoggerInterceptor] *** Entering method: destroy
                    14:32:51,173 INFO [Contexts] starting up: org.jboss.seam.web.session
                    14:32:51,173 INFO [Contexts] starting up: org.jboss.seam.security.identity


                    PeerAction is not being destroyed....

                    • 7. Re: resetting/clearing a session scoped SFSB
                      asookazian

                       

                      "pete.muir@jboss.org" wrote:
                      "asookazian" wrote:
                      hmm. when the user selects another manager in the h:selectOneMenu, it's like they're started another session (similar to logging in as another user).


                      So, then invalidate the session.


                      I built and deployed the spring example from 2.0.0.GA. The following code in LoginAction:

                      public void logout() {
                       loggedIn = false;
                       Seam.invalidateSession();
                       }


                      is called from template.xhtml:

                      <s:link id="logout" action="#{login.logout}" value="Logout"/>


                      when I register, login and then click logout link, I am redirected to:

                      http://localhost:8080/jboss-seam-spring/home.seam

                      Not sure exactly how this works but irrespective, my use case is different. We are using NTLM via JCIFS library to extract username from IE browser for authentication (i.e. there is no physical login for user).

                      In this case, user selects another peer manager from drop-down and sees a modalPanel with continue and cancel buttons. If they click continue, this is where I need to invalidate the session(s) and load the @Factory dataModel for the appropriate manager.

                      So basically, the spring logout is not what I need, I need to invalidate the session(s) and reload the form/dataTable immediately...


                      • 8. Re: resetting/clearing a session scoped SFSB
                        asookazian

                        Oh I see. In pages.xml for the spring example is how it's redirected back home:

                        <page view-id="*">
                        
                         <navigation from-action="#{login.logout}">
                         <redirect view-id="/home.xhtml"/>
                         </navigation>
                        
                         <navigation from-action="#{hotelBooking.cancel}">
                         <redirect view-id="/main.xhtml"/>
                         </navigation>
                        
                         </page>


                        • 9. Re: resetting/clearing a session scoped SFSB
                          asookazian

                          <p>It seems that Seam destroys the SFSB's after the JSF has been reRendered by the clicking of the continue button in the following xhtml code: <br/><a href="

                          <a4j:form id="a4jChangePeer">

                                                <h:outputText value="Are you sure you want to switch to a peer?  You will lose all unsaved changes."/>

                                                <BR/>

                                                <h:panelGrid columns="2">

                                                     <a4j:commandButton value="Continue"

                                                                            action="#{securityAuditAction.invalidateSession}"

                                                                            onclick="Richfaces.hideModalPanel('mpChangePeer')"

                                                                                  ajaxSingle="true"

                                                                                  reRender="mainForm"/>

                                                     <BR/>

                                                     <a4j:commandButton value="Cancel" onclick="resetPeerMenu(); Richfaces.hideModalPanel('mpChangePeer')"/>

                                                 </h:panelGrid>

                                       </a4j:form>">

                          <a4j:form id="a4jChangePeer">

                                                <h:outputText value="Are you sure you want to switch to a peer?  You will lose all unsaved changes."/>

                                                <BR/>

                                                <h:panelGrid columns="2">

                                                     <a4j:commandButton value="Continue"

                                                                            action="#{securityAuditAction.invalidateSession}"

                                                                            onclick="Richfaces.hideModalPanel('mpChangePeer')"

                                                                                  ajaxSingle="true"

                                                                                  reRender="mainForm"/>

                                                     <BR/>

                                                     <a4j:commandButton value="Cancel" onclick="resetPeerMenu(); Richfaces.hideModalPanel('mpChangePeer')"/>

                                                 </h:panelGrid>

                                       </a4j:form></a> <br/> <br/>So the invalidateSession method is marked with @End, when exactly does the SFSB get destroyed?  It seems it happens after the reRendering of the JSF and in my case that's too late.  When the JSF reRenders, it displays the data from the original dataTable....</p>