2 Replies Latest reply on Apr 18, 2008 11:16 PM by Mark Anderson

    POJO and context question

    Mark Anderson Newbie

      I'm fairly new to both Seam and JSF and am having problems with a POJO that's acting like it's in application scope, though I've not set it up that way. 


      The POJO (default/event context) is being outjected from a SLSB and am populating an xhtml page that is being used for both the submit and the response-display of the POJO values.  That part works fine, but when I navigate to different pages in my application (via s:link) and then return to that xhtml page, the page is still populated with values from the POJO.  Shouldn't the POJO be out of scope at this point? 


      But now the really strange part is that I can even log out of the application (identity.logout), and upon logging back in, the previous values are still being displayed on the page in question.


      So, it seems like the POJO is acting like it's in the application context.  It does not show up in the debug.seam page under application context directly, but is listed under/with my SLSB component (and I don't understand why all the components including stateless ones show up under application context in debug.seam either?).


      In my stateless bean:


      @Stateless
      @Name("calculator")
      public class CalculatorAction implements Calculator {
      
      ...
      @Out(required=false,scope=ScopeType.EVENT)
      private CustomerDTO customerDTO;
      ...
      



      In the xhtml:


      <rich:panel rendered="#{customerDTO.accountNumber ne null}">
      ...
      <s:decorate id="city" template="layout/display.xhtml">
           <ui:define name="label">City</ui:define>
                       <h:outputText value="#{customerDTO.city}"/>
      </s:decorate>
      ... etc.
      


      The only related thing in pages.xml:


           <page view-id="/calculator.xhtml" 
                login-required="true">
           </page>
      


      The menu links used for navigation between pages:


      <s:link view="/home.xhtml" value="Home" />
      <s:link view="/test.xhtml" value="Test" />
      <s:link view="/calculator.xhtml" value="Calculator" />
      



      This is Seam 2.0.1.GA on JBoss 4.2.0 CP02 EAP


      Ideas?  Thanks.

        • 1. Re: POJO and context question
          Tom Goring Apprentice

          i think your problem here is that customerDTO is an instance variable of your stateless session bean.  that session bean will be shared between various http requests (from a pool).


          In general it is a bad idea to have instance variables like this on a stateless component.


          You could



          1. make CalculatorAction just a pojo that is conversation or event scoped

          2. try and also annotate customerDTO with @In(required=false) so the last values is removed

          3. Make CalculatorAction a @Statefull session bean




          hope this helps.

          • 2. Re: POJO and context question
            Mark Anderson Newbie

            Thanks Tom.  Your ideas lead me to a fix and it's working now.


            I needed to re-think the whole SLSB thing for Seam.  Coming from a Struts background, we use a lot of SLSBs as session facades.  I was trying to do what the Seam equivalent of that was but was thrown by the frequent use of instance variables with @In and @Out in SLSB examples in the Seam docs and books.




            In general it is a bad idea to have instance variables like this on a stateless component.


            I would agree with that in a non-Seam environment, but in Seam it seems to be common -- at least from the many examples I've been seeing.  I was just not going about it correctly, and am pretty sure I was still seeing values from the already-used SLSB before it was released by the container.  Applying the @In(required=false) did fix it when I first tried it, but I had other problems too that needed to be resolved.


            Since I didn't really need a SLSB at this point anyway, I converted CalculatorAction into a POJO, set it to event context and made some other tweaks once I had a better understanding of what was going on.


            In addition to your comments, a couple of other things that helped me grasp this a bit better were these two quotes (in case others are trying to understand this better too):


            From Seam reference docs (the last sentence here):




            3.2.1. Stateless session beans
            Stateless session bean components are not able to hold state across multiple invocations. Therefore, they usually work by operating upon the state of other components in the various Seam contexts. They may be used as JSF action listeners, but cannot provide properties to JSF components for display.


            From one of the Seam books:





            BIJECTION WITH STATELESS SESSION BEANS



            One thing that should be noted before we continue is that the bijection in Seam is actually very complex (in a good way). Case in point: how we deal with stateless session beans. If you have worked with them in the past, you are used to a simplistic model in which you send data to the SLSB, it performs some operation, and then you return data. You never have the SLSB access property-specific data on the SLSB. It is not safe to do so with SLSBs, unless the property is a global object such as a database connection or logger reference.




            However, with Seam this methodology is thrown out the window a bit. Seam does not use a simplistic creation-time IoC. Instead the bijection happens at invocation. Therefore, the objects you are setting with @In or @Out to be injected or outjected are done at invocation, and when the method is complete, they are disinjected. This is what makes it safe for us in Seam to reference properties of the SLSB inside the methods.


            Those two sound a bit contradictory, but they both helped grasp the needed changes, along with your original comments.  Thanks.