10 Replies Latest reply on Oct 9, 2008 10:32 PM by hermida.leandro.hermida.gmail.com

    how to create applications where entity beans are not Seam components

    hermida.leandro.hermida.gmail.com
      In the Seam manual in chapter 4.2.3 Entity Beans its mentioned:

      "Note that it in a clustered environment is somewhat less efficient to bind an entity bean directly to a conversation or session scoped Seam context variable than it would be to hold a reference to the entity bean in a stateful session bean. For this reason, not all Seam applications define entity beans to be Seam components."

      Being a somewhat of a newbie I am having trouble understanding how one creates and application where none of your entity beans are Seam components.  I understand so far how in a Seam component session bean one can inject with @In and outject with @Out entity beans that are not Seam components and also even give them scope. 

      As an example, a User entity bean that is not a Seam component:

      @Entity
      @Table(name="USER)
      public class User
      ...

      Then a Seam component session bean:

      @Stateful
      @Name("registerAction")
      @Scope(CONVERSATION)
      public class RegisterAction ....

      @In(create = true)
      User registerUser;

      Then in the Facelets page register.xhtml I use registerUser in JSF EL:

      <h:inputText required="true" value="#{registerUser.firstName}"/>
      <h:inputText tabindex="1" size="40" maxlength="63" required="true" value="#{registerUser.lastName}"/>
          
      You get error of the form: "Target Unreachable, identifier 'registerUser' resolved to null"

      Am I doing something wrong? How does one use entity bean non-Seam components in the view layer?
        • 1. Re: how to create applications where entity beans are not Seam components
          gjeudy

          You cannot use:


          @In(create = true)

          as an instantiation strategy for non-seam managed components.


          try:


          @Factory

          or instantiate yourself the entity and use

          @Out

          in one of your EJB or java beans.


          Note that if you use

          @Out

          you have to execute an action method that will do the instantiation and assign it to your instance var to be outjected.

          • 2. Re: how to create applications where entity beans are not Seam components
            hermida.leandro.hermida.gmail.com

            Hi everyone,


            Sorry to come back to this for some more clarification after such a long time.  Based on your advice the following code works when the User entity bean is not a Seam component:



            @Stateful
            @Name("registerAction")
            @Scope(CONVERSATION)
            public class RegisterAction ....
            
                @In(required = false)
                User registerUser;
                
                @Factory("registerUser")
                public User getRegisterUser {
                    return new User();
                }
            
                public String register {
                    // here I would user registerUser injected context variable to do registration
                }
            }



            And the Facelets page has the same as before:


            <h:inputText required="true" value="#{registerUser.firstName}"/>
            <h:inputText tabindex="1" size="40" maxlength="63" required="true" value="#{registerUser.lastName}"/>



            My question is, is the following ok practice for making Seam applications where none of my entity beans are Seam components?


            Thanks,
            leandro


            • 3. Re: how to create applications where entity beans are not Seam components

              Just look at the examples in jboss-seam-2.0.2.SP1\examples you will not find a single @Entity with a @Name


              Therefore the recommended practice is:


              None of your entity beans (@Entity) should be Seam components (@Name).


              • 4. Re: how to create applications where entity beans are not Seam components
                hermida.leandro.hermida.gmail.com

                Hi Francisco,


                Thank you for the reply, yes this I understood - my question was though is the way I wrote the code above (using @Factory to generate a new entity instance when the xhtml form loads and @In(required = false) to inject it back from the form fields during form submission) the right way?  Or is there a better way to write such code when no entities are Seam components?


                leandro

                • 5. Re: how to create applications where entity beans are not Seam components

                  Leandro Hermida wrote on Oct 09, 2008 17:27:


                  Hi Francisco,

                  Thank you for the reply, yes this I understood - my question was though is the way I wrote the code above (using @Factory to generate a new entity instance when the xhtml form loads and @In(required \= false) to inject it back from the form fields during form submission) the right way?



                  I have not seen @Factory used that way... I use it only for times when i read stuff from the database. But I couldn't say it is plain wrong, I guess it depends on what you are trying to achieve, I guess I would have written it like this:

                  @Name("registerAction")
                  @Scope(PAGE)
                  public class RegisterAction ....
                  
                      private User registerUser;
                      
                      public User getRegisterUser() {
                          if(registerUser==null)
                            registerUser = new User();
                      }
                  
                      public String register {
                          // here I would user registerUser to do registration
                      }
                  }
                  



                  Unless, of course, I would want to pass the registerUser to a different page, but, if I only want to work with it in the current page, then I guess the PAGE scope is better for the job than CONVERSATION, and since all the class is in that Scope, all values are preserved as long as I do not redirect to another page.



                  I almost forget to write this, with my approach the EL expressions in your xhtml changes:

                  <h:inputText required="true" value="#{registerAction.registerUser.firstName}"/>
                  <h:inputText tabindex="1" size="40" maxlength="63" required="true" value="#{registerAction.registerUser.lastName}"/>
                  



                  But that is just my way to do things. You can find yours.




                  Or is there a better way to write such code when no entities are Seam components?



                  I do not mean to be rude, but , please don't ask what to do when no entities are Seam components, because that is like asking: what to do always?. Remember: entities should never be Seam components.



                  leandro



                  Click HELP for text formatting instructions. Then edit this text and check the preview.

                  • 6. Re: how to create applications where entity beans are not Seam components
                    gjeudy

                    Leandro,


                    You don't need to use @In(required=false), @In should do,


                    Seam will resolve your registerUser variable name in the EL context, if it doesn't see it in existence in Seam contexts (hierarchical search from narrowest to broadest context) it will check if any @Factory or @Unwrap are registered with registerUser EL expression and will execute the attached method to produce the value that will then be outjected to the relevant Seam context.


                    Other than that I think you approach looks good.

                    • 7. Re: how to create applications where entity beans are not Seam components
                      hermida.leandro.hermida.gmail.com

                      Hello,


                      Ok thank you this is much clearer now.


                      Don't worry you were not rude at all - but I should say that if entities should never be Seam components then why does Seam allow it at all?  And also why do the Seam Reference docs show so many examples with @Name on an @Entity?  It is very confusing to us newbies to learn then the right way :)


                      leandro

                      • 8. Re: how to create applications where entity beans are not Seam components

                        Leandro Hermida wrote on Oct 09, 2008 18:09:


                        Hello,

                        Ok thank you this is much clearer now.

                        Don't worry you were not rude at all - but I should say that if entities should never be Seam components then why does Seam allow it at all?


                        I have to admit that confuses me too, specially because AFAIK none of the examples that come with Seam use @Name in an @Entity. Perhaps the Seam team thinks there might be some use cases where it is a good idea to mix @Name and @Entity. Perhaps to support Domain Driven Design by allowing us to inject services into @Entity objects? But I got the feeling that the Hibernate/Seam guys do not like that idea.


                          And also why do the Seam Reference docs show so many examples with @Name on an @Entity?  It is very confusing to us newbies to learn then the right way :)



                        That is a really good question.



                        leandro



                        Click HELP for text formatting instructions. Then edit this text and check the preview.

                        • 9. Re: how to create applications where entity beans are not Seam components
                          gjeudy

                          I would like to add that having entities not seam components is good for another reason not mentioned in this thread.


                          It is good for performance because by exposing entities to the view you allow JSF to potentially make dozens of calls to your entities going through the interception logic on every method call. A good example of this is rendering a dataTable of entities.


                          I also discovered something on my project, if you have good reasons to create your mappings in XML instead of annotations Seam will not handle your entity well if you try to Seam componentize it.

                          • 10. Re: how to create applications where entity beans are not Seam components
                            hermida.leandro.hermida.gmail.com

                            Hi - Thanks this is very useful information to the Seam community, details you don't find in the docs!