5 Replies Latest reply on Aug 13, 2009 3:46 PM by judy guglielmin

    Simple Backing Bean Question

    Matthew Bowman Newbie

      My setup is Seam 2.2.0.GA, ICEfaces 1.8.1 and JBoss AS 5.1.0.GA.


      I have a simple entity bean:


      @Name("applicant")
      @Entity
      public class Applicant implements Serializable {
      
          @Id @GeneratedValue
          private Long id;
      
          private String firstName;
      
          private String lastName;
      
          /* getters & setters removed for brevity */
      
      }



      And a simple form


      <ice:form>
        <h:inputText value="#{applicant.firstName}" />
        <h:inputText value="#{applicant.lastName}" />
        <ice:commandButton value="Submit" 
          partialSubmit="false" 
          action="#{applicantionSubmitAction.submit}" />
      </ice:form>



      And a simple action listener


      @Name("applicationSubmitAction")
      public class ApplicationSubmitAction {
      
          @In
          private Applicant applicant;
      
          public void submit() {
              /* submit-to-db logic here */
          }
      
      }



      Now with this setup if I log the injected applicant's firstName and lastName, they are set with the values from the form. But if I persist the injected instance to the DB using entityManager.persist(applicant) all the columns are null. I ran this in debug mode with eclipse and the variables getting injected into the action listener have been proxied (they are wrapped with javassist code).


      So this made me think about adding the @BypassInterceptors annotation to my entity bean


      @Name("applicant")
      @Entity
      @BypassInterceptors
      public class Applicant ...



      ... and that did the trick.


      Now my question is what am I doing wrong? In both the message and registration examples, they achieve very similar functionality but do not require the @BypassInterceptors annotation.


      Should I be associating these components with a particular scope?


      Thanks in advance,
      --mgbowman

        • 1. Re: Simple Backing Bean Question
          Arbi Sookazian Master

          I'm pretty sure that you don't need @BypassInterceptors, that is a performance optimization tactic which turns off bijection, for example.


          The default scope for JavaBean is EVENT and for entity class is CONVERSATION.


          How are you injecting the EntityManager?


          It seems to me that even with the default settings, this should work w/o @BypassInterceptors.


          So you're saying that the insert is committing to the db and you see a new record but the setter values are null?


          What are the values for the relevant properties in the entity class prior to persist() call?

          • 2. Re: Simple Backing Bean Question
            Matthew Bowman Newbie

            If I log the properties - i.e. log.info("applicant.firstName='{0}'", applicant.getFirstName()); - the values are those submitted via the form.


            However, running JBoss in debug mode and putting a breakpoint on the #{applicationSubmitAction.submit} action, I can see the injected applicant instance has been proxied / intercepted for some reason - it's not just a POJO.


            In Eclipse, it's class type is listed as Applicant_$$_javassist_seam_5 which is a sure sign the original class was instrumented using javassist. Inspecting the instance, the firstName and lastName properties are set to null and it has an additional property handler which points to an instance of org.jboss.seam.intercept.JavaBeanInterceptor. The interceptor has a bean property which appears to be the instance from the form (because it's firstName and lastName properties are the values from the form). It's beanClass property is the Class instance of my Applicant class.


            Why is javassist coming into play on a simple form submission? The only thing I can think of is it has something to do with my configuration and the fact I'm using ICEfaces instead of RichFaces.


            Thanks in advance,


            --mgbowman

            • 3. Re: Simple Backing Bean Question
              heapifyman heapifyman Newbie

              In your form you have:


              action="#{applicantionSubmitAction.submit}" />



              I suppose that's a type?


              But shouldn't it be:


              <h:inputText value="#{applicationSubmitAction.applicant.firstName}" />
              <h:inputText value="#{applicationSubmitAction.applicant.lastName}" />


              • 4. Re: Simple Backing Bean Question
                heapifyman heapifyman Newbie

                philip r. wrote on Aug 13, 2009 12:52:


                I suppose that's a type?


                Should be: I suppose that's a typo?

                • 5. Re: Simple Backing Bean Question
                  judy guglielmin Novice

                  Just a note that partialSubmit defaults to false, so if you don't want it, just leave it out. (then things act like regular jsf).  When you bypass the interceptors, that just means that any injection on the methods and attributes of a class (basically annotations from Seam like In, Out, DataModel, etc) are not available to you.  It really doesn't have much to do with the jsf lifecycle. Last poster is correct, since you are setting the entity values within your manager class (with an instance of your entity there), you will only have it available there in the scope of your manager class. Also, it's nice to debug with ICEfaces by having partialSubmit to true on your input components and don't bother with a submit button. You can then see immediately what the input from that component does within the app with a blur (tab out, enter,..) on that component.