8 Replies Latest reply on Sep 25, 2006 4:02 PM by gavin.king

    Using the @Factory annotation and stateless session beans

    zzzz8

      I'm wondering why my method that's marked with the @Factory annotation in my stateless session bean isn't being invoked. Because I'm still new to EJB and Seam, I'm wondering if I don't understand the concepts well enough yet. Here's what I have (some sample code - the syntax may not be entirely correct - but my actual code compiles):

      My stateless session bean implementation:

      @Name("TestStatelessBean")
      @Stateless
      public final class TestSLSBBean implements TestSLSBLocal {
       @Out(value="testVar")
       private String testVar = null;
      
       @Factory("testVar")
       public void init() {
       ....
       }
      
       public void testSLSBMethod() {
       ....
       }
      }


      The business interface for this bean:

      @Local
      public interface TestSLSBLocal {
       void init();
      
       void testSLSBMethod();
      }


      The stateless session bean is invoked from a stateful session bean with the default conversation scope:

      @Name("TestStatefulBean")
      @Stateful
      public final class TestSFSBBean implements TestSFSBLocal {
       @In(value="TestStatelessBean", create = true);
       TestSLSBLocal test;
      
       void testSFSBMethod() {
       test.testSLSBMethod();
       }
      }


      So when test.testSFSBMethod() is invoked, the init method in TestStatelessBean is somehow never invoked before testSLSBMethod is called (at least it doesn't appear so in my debugger). I would hate to have to add the init() method call to everyone one of the methods in the TestSLSBBean class. What am I doing wrong, or do I have to add init() for each method in the TestSLSBBean class? Thanks!

        • 1. Re: Using the @Factory annotation and stateless session bean
          gavin.king

          I don't understand why you think the @Factory method should be called. Nothing ever references testVar.

          Perhaps you have confused @Factory with @Create?

          • 2. Re: Using the @Factory annotation and stateless session bean
            zzzz8

            Hi Gavin,

            Thanks for the reply. Actually, something in the init and testSLSBMethod methods would reference testVar. I just left that out.

            In terms of @Create, is that not possible from a stateless session bean? Thanks!

            • 3. Re: Using the @Factory annotation and stateless session bean
              gavin.king

               

              Thanks for the reply. Actually, something in the init and testSLSBMethod methods would reference testVar.


              No, what references the testVar *context variable*, not the testVar instance variable? Do you understand what @Factory is for?

              In terms of @Create, is that not possible from a stateless session bean?


              Correct, I forgot about that.


              It would help if you described what you are actually trying to *achieve*, with a more meaningful example than TestStatefulBean, TestStatelessBean, testVar, etc. This doesn't help me understand the usecase.

              • 4. Re: Using the @Factory annotation and stateless session bean
                zzzz8

                What I'm trying to achieve (or figure out) is why the init method isn't being invoked when I call the testSLSBMethod. I assumed that because the init method has been annotated with a Factory annotation and the testVar component is initially null - that this would cause the init method (i.e. method annotated with the Factory annotation) to be invoked whenever one invokes any business method in the stateless session bean (in this case, testSLSBMethod in TestSLSBBean stateless session bean).

                Ultimately, my question is whether one can use the @Factory annotation within a stateless session bean. - and whether I'm using it incorrectly in my example. My understanding is that a method marked with the Factory annotation is called whenever the context variable that the Factory annotation references is null. Thanks!

                • 5. Re: Using the @Factory annotation and stateless session bean

                   

                  I assumed that because the init method has been annotated with a Factory annotation and the testVar component is initially null - that this would cause the init method (i.e. method annotated with the Factory annotation) to be invoked whenever one invokes any business method in the stateless session bean (in this case, testSLSBMethod in TestSLSBBean stateless session bean).


                  This is your mistake. Factory methods are only called when something looks for testVar in a Seam context and it isn't already there. So if your JSF page tried to display #{testVar} or another componented tried a @In(value="testVar"), etc. Simply referencing the instance variable testVar in a method won't get the job done. The difference is between the notion of an instance variable and a *context* variable.

                  • 6. Re: Using the @Factory annotation and stateless session bean

                    If you want something run on every invocation in a SLSB (or anything else for that matter), you're looking for an interceptor. Check out the @LoggedIn interceptor in the booking example for a simple implementation. The manual covers this interceptor in section 2.6

                    All @Factory does is initialize a component that's in an instance variable, and it'll only be called if it's not already set. It's not the best name I can think of, since @Unwrap is the annotation that actually yells "Factory Method" to me. But even @Unwrap is not going to give you the behavior you want, only an interceptor will.

                    @Factory is used all over the examples. The blog example has some of the best uses of it, though the booking and dvdstore examples are probably easier to understand.

                    • 7. Re: Using the @Factory annotation and stateless session bean

                      The difference between @Factory and @Unwrap is that @Unwrap only works on components. @Factory can work on contextual variables as well, like the String example given.

                      • 8. Re: Using the @Factory annotation and stateless session bean
                        gavin.king

                        @Unwrap is not just a "factory". It can be used to do MUCH more than just auto-instantiate something.

                        @Factory is used when you just want to auto-initialize some value from a component.

                        @Unwrap is used when the component really "manages" the value.