4 Replies Latest reply on Jun 8, 2006 9:41 AM by mmarcom

    Seam question regarding @In  annotation and request params

    mmarcom

      hi all,
      i have written a small Seam application that resembles a shopping cart. I have a EcontrolSession bean, and two entity beans, Expense and Items.
      I am adding items to the expense bean and then i plan to persist the expense via the SessionBean

      My question is:
      - my Session bean is stateful and has a session scope
      - my Expense entity will be a global variable in the EControlSession bean, because it lasts for the lifespan of user session
      - My Item will have a request scope because user enters items at every request.

      My thought was that . this would have worked

      @Stateful
      @Local ( {EControlSession.class})
      @Name("econtrol")
      
      
      @Scope(SESSION)
      
      
      
      public class EControlSessionBean
       implements EControlSession, java.io.Serializable
      {
      
      
       private Expense expense = new Expense();
      
       @In(create=true)
       private Item item = new Item();
      
       @PersistenceContext
       EntityManager em;
      
      
      
       int counter = 0;
      
      
      
       /**
       * Add an user (Admin only should access this)
       */
       public void addExpense (Expense expense) {
       System.err.println("Persisting expense");
       em.persist(expense);
       System.err.println("Expense persisted..");
       }
      
       public Expense getExpense() {
       return expense;
       }
      
      
       public Item getItem() {
       return item;
       }
      
       public String add() {
      
       item.setName("test" + 1);
       item.setPrice(1);
      
      
       expense.addItem(item);
      
       return "success";
       }
      ...
      


      and here's my page

      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:s="http://jboss.com/products/seam/taglib"
       template="template.xhtml">
       <ui:define name="body">
      
       <h2> Adding Product</h2>
       <h:messages/>
      
       <f:view>
       <h:form id="foobrrewwe">
       <table>
       <tr>
       <td>Site:<h:outputText value="#{econtrol.expense.site}"/></td>
       <td>Date:<h:outputText value="#{econtrol.expense.date}"/></td>
       </tr>
       </table>
       <table>
       <tr>
       <td>Product Name</td>
       <td><h:inputText value="#{econtrol.item.name}"/></td>
      
       </tr>
      
       <tr>
       <td>Price</td>
       <td><h:inputText value="#{econtrol.item.price}">
       <f:converter converterId="javax.faces.Double"/>
       </h:inputText>
       </td>
       </tr>
      
       </table>
      
       <h:commandButton action="#{econtrol.add}" value="Add Item"
       class="formButton" style="width: 166px;" />
       <h:commandButton action="#{econtrol.stop}" value="Finish"
       class="formButton" style="width: 166px;" />
      
       </h:form>
       </f:view>
      
       <h4><a href="register.seam">Back To Index</a></h4>
       </ui:define>
      
      </ui:composition>
      



      my assumption was because i thought that @In somehow resolved to a getter and setters, so that the Item object can be populated using

      <h:inputText value="#{econtrol.item.price}/>


      as i have found out, it does not work that way...

      is the only way out for me to declare two @request variable and populate each item with those requet variables?

      thanks and regards
      marco










        • 1. Re: Seam question regarding @In  annotation and request para
          iradix

          Injection occurs either on a field or on a setter depending on where you place the @In annotation. It seems to me like you are confusing injection with jsf data binding however. What exactly is happening and what did you expect?

          • 2. Re: Seam question regarding @In  annotation and request para
            mmarcom

            Hello,
            what i was expecting was that
            - a new Item is created every time a method on teh Session bean is called (which i think it happens, due to the @In create=true annotation)

            and i thought that this code

             <tr>
             <td>Product Name</td>
             <td><h:inputText value="#{econtrol.item.name}"/></td>
            
             </tr>
            
             <tr>
             <td>Price</td>
             <td><h:inputText value="#{econtrol.item.price}">
             <f:converter converterId="javax.faces.Double"/>
             </h:inputText>
             </td>
             </tr>
            
             </table>
            


            on the jsf was going to be bound to the @item object injected, after this creation.

            Effectively, as i realized afterwards, my assumption were wrong..

            so, my goal was to create a new Item every time the addItem method of the sessio bean is called, and that item has to be populated with request parameter..

            i guess the solution will be to define two variables with @Request parameter and in the addItem method populate the Item created with those two @requestparameter annotation.

            The only thing I AM MISSING is how to write the jsf in order to associate entered values to the two @RequestParameter variables

            for example, assume that i declare in the SessionBean those two variables

            Local ( {EControlSession.class})
            @Name("econtrol")
            @Scope(SESSION)
            public class EControlSessionBean
             implements EControlSession, java.io.Serializable
            {
            @RequestParameter{"price"}
            double price;
            
            @RequestParameter{"name"}
            String name;
            
            ...
            


            what will i put in my jsf now?

            <h:inputText value="#{econtrol.price}"/>
            ..
            


            but then i'll need to write also getter/setters for those two variables..otherwise JSF validation will fail....

            sorry for the confusion.... could you help me one more time?

            thanks and regars
            marco




            • 3. Re: Seam question regarding @In  annotation and request para
              iradix

              Marco,

              Using request parameters is absolutely not the right way to do it. Your original concept is correct, it seems like it just needs some tweaking. To tell you the truth, I'm not really sure why you are using Seam to create your Item instances in the first place. Try removing the @In(create=true) annotation from your Item leaving the item = new Item() statement and then in your add method after expense.addItem(item) add the statement item = new Item();. I have a feeling that what was happening is that a new Item instance was getting injected after JSF data binding had occured thereby overwriting anything that came in from the page. Let me know how that works out.

              • 4. Re: Seam question regarding @In  annotation and request para
                mmarcom

                hello,
                thanks.. i followed ur suggestion and it worked just fine

                >>To tell you the truth, I'm not really sure why you are using Seam to create >> your Item instances in the first place.

                i did it becuase i thought that with the @In annotation i could have injected an object that i could have reused also on the JSF side (like i did with normal JSFs, i 'injected' a component via faces-config and i was reuisng it for the web. i thought it would have worked the same... i was wrong..thanks for guiding me toward the correct solution)


                thanks again and regards
                marco