5 Replies Latest reply on Mar 23, 2010 4:17 PM by jlsimone

    How to initialize the State of an EJB3 Stateful Bean

    jlsimone
      In EJB2, you can pass the state to a stateful EJB using the home interface and the arguments that are defined for the ejbCreate method of the bean. This seems like it should be a simple thing do to, and I feel a little dumb asking the question, but how do you pass the state into an EJB3 stateful bean? All of the documentation that I have read so far assumes that the EJB creates its own state when the (no-arg) constructor is called. But in my case, the business logic of the application has already created a state (in the form of an object tree) that it needs to pass into the stateful bean. I have created what I consider a hack, which is to expose an "initialize" method in the remote/local interface. The initialize method  sends the state to the EJB in the arguments of the method arguments. What are the better options for doing this?
        • 1. Re: How to initialize the State of an EJB3 Stateful Bean
          jaikiran

          You can use @Init. Here's what the EJB3 spec says:

           

          Section 4.3.10.1 of EJB3 Spec:

          If the bean is a stateful session bean and the client has used one of the create<METHOD> methods defined in the session bean’s home or local home interface to create the bean, the container then calls the instance’s initialization method whose signature matches the signature of the create<METHOD> invoked by the client, passing to the method the input parameters sent from the client. If the bean class was written to the EJB 3.0 API, and has been adapted for use with an earlier client view, this initialization method is a matching Init method, as designated by use of the Init annotation, or init-method deployment descriptor element[12]. If the bean class was written to the EJB 2.1 or earlier API, this initialization method is a matching ejbCreate<METHOD> method, as described in Section 4.6.4.

          • 2. Re: How to initialize the State of an EJB3 Stateful Bean
            wolfc

            Unless you go down the road of creating an EJB 2.1 view with a home interface with the appropriate create methods, your 'hack' is the actual solution.

            On lookup you get an 'empty' stateful bean which you need to fill in any way confortable with you. If you want you can even create a regular create method which mimicks the home interface:

            interface MyRemote {
               MyRemote create(String state);
            }
            
            class MyBean implement MyRemote {
               MyRemote create(String state) {
                  this.state = state;
                  return ctx.getBusinessObject(MyRemote.class);
               }
            }
            

            The only important thing to remember is that the initial lookup associates your stateful session, instead of a create call on a (home) interface.

            1 of 1 people found this helpful
            • 3. Re: How to initialize the State of an EJB3 Stateful Bean
              jlsimone

              Thanks for the information, Carlo. I have a couple of questions. What is the ctx variable you reference in your example? I assume it is some kind of context object. Where is it initialized, how is it created?

              • 4. Re: How to initialize the State of an EJB3 Stateful Bean
                jlsimone

                ... Reply to my own post, answer to my own question.

                 

                Using EJB3 @Resource annotation.

                • 5. Re: How to initialize the State of an EJB3 Stateful Bean
                  jlsimone

                  Wow.  I just discovered something. Not only does Carlo's example code initialize the state of the stateful EJB, I modified it to solve another problem that I was having. Here is my modified example below.

                   

                  interface MyLocal {
                     MyRemote create(String state);
                  }

                   

                  interface MyRemote{
                     void doWork();

                  class MyBean implement MyRemote, MyLocal {
                     MyRemote create(String state) {
                        this.state = state;
                        return ctx.getBusinessObject(MyRemote.class);
                     }
                    
                     void doWork(){
                        // do something
                     }
                  }

                   

                   

                  What I've done here is I have given the local interface the responsibility of creating the bean. This allows me to create one EJB from another EJB in the same JVM, passing the state to the second EJB by reference (instead of by value) via the local interface. This probem is described in a question I posted in another discussion thread. The link is http://community.jboss.org/thread/147136.

                   

                  The link, above, describes a problem where I am using EJBx to create EJBy within the same JVM. After I create EJBy, I  pass the remote interface for EJBy to the remote client. My problem was that I was using the remote interface (pass by value) to initailize the state of EJBy. But Carlo's modified example allows me to initialize EJBy using the local interface (pass by reference) and then have the create method return the remote interface that is needed by the remote client.