6 Replies Latest reply on Aug 8, 2008 10:08 PM by infinity2heaven

    how to pass variables between 2 SFSBs

    infinity2heaven

      I have two SFSB's A and B (pretty simple). I need to call B.foo(variableB) from A.


      @In(create=true)  @Out(required=false)   
      private xxx variableB;



      I have a redirect in my pages.xml and B.foo does get called. However the variableB is not initialized to the value I passed from A. Because both are conversation scoped by default, I'd imagine that the moment SFSB B is called, the values from older conversation is not accessible here.


      I read a lot about nested conversations and making variableB as  @out(scope=SessionScope)
      but I'm not sure whats the correct way to implement this.


      Any pointers?


      The idea is to freely navigate to/from multiple session beans with variables being passed.

        • 1. Re: how to pass variables between 2 SFSBs
          admin.admin.email.tld

          This is most definitely doable.  Post the implementation classes for the two session beans.  Otherwise, check out the booking example or other Seam distro examples.  this is a very common activity in Seam code.

          • 2. Re: how to pass variables between 2 SFSBs
            infinity2heaven

            I'm implementing basic CRUD screens but with some sophisticated UI layouts.  EntityHome is full of bugs, doesn't work for all. So here is my code


            @Stateful
            @Name(value = "fofAdmin")
            public class FofAdminAction extends EntityController implements FofAdmin {
            
                 static Log log = LogFactory.getLog(FofAdminAction.class.getName());
            
                 @In(create = true)
                 @Out(required = false)
                 private Fof selectedFof;
            
                 @In(create = true)
                 private FundAdmin fundAdmin;
            
                 public void view(Fof viewFof) {
                      log.debug("viewing fof - " + viewFof);
                      selectedFof = viewFof;
                 }
            
                 public void add() {
                      // clear the existing fof
                      selectedFof = new Fof();
                 }
            
                 public void save() {
                      persist(selectedFof);
                      addFacesMessage(ASRUtils.displayCrudMessage("save"));
                 }
            
                 public void delete() {
                      remove(selectedFof);
                      addFacesMessage(ASRUtils.displayCrudMessage("delete"));
                 }
            
                 public void update() {
                      merge(selectedFof);
                      addFacesMessage(ASRUtils.displayCrudMessage("update"));
                 }
            
                 @Factory(value = "selectedFof")
                 public Fof initSelectedFof() {
                      return new Fof();
                 }
                 
                 public void switchToFundAdmin(Fund fund) {
                      log.debug("Switching to Fund Admin for fund - " + fund);
                      fundAdmin.view(fund);
                 }
            
                 @Remove
                 @Destroy
                 public void destroy() {
                      log.debug("FofAdminAction: destroy ...");
                 }
            }



            The other one is 95% identical



            @Stateful
            @Name(value = "fundAdmin")
            public class FundAdminAction extends EntityController implements FundAdmin {
            
                 static Log log = LogFactory.getLog(FundAdminAction.class.getName());
            
                 @In(create = true)
                 @Out(required = false)
                 private Fund selectedFund;
            
                 @In(create = true)
                 private FofAdmin fofAdmin;
            
                 public void view(Fund viewFund) {
                      log.debug("viewing fund - " + viewFund.getName());
                      selectedFund = viewFund;
                 }
            
                 public void add() {
                      // clear the existing fund
                      selectedFund = new Fund();
                 }
            
                 public void save() {
                      persist(selectedFund);
                      addFacesMessage(ASRUtils.displayCrudMessage("save"));
                 }
            
                 public void delete() {
                      remove(selectedFund);
                      selectedFund = new Fund();
                      addFacesMessage(ASRUtils.displayCrudMessage("delete"));
                 }
            
                 public void update() {
                      merge(selectedFund);
                      addFacesMessage(ASRUtils.displayCrudMessage("update"));
                 }
            
                 @Factory(value = "selectedFund")
                 public Fund initSelectedFund() {
                      return new Fund();
                 }
            
                 public void addAlias() {
                      selectedFund.addAlias(new FundAlias());
                 }
            
                 public void removeAlias(FundAlias alias) {
                      selectedFund.removeAlias(alias);
                 }
            
                 public void switchToFofAdmin(Fof fof) {
                      log.debug("Swithcing to Fof Admin");
                      fofAdmin.view(fof);
                 }
            
                 @Remove
                 @Destroy
                 public void destroy() {
                      log.debug("FundAdminAction: destroy ...");
                 }
            }



            I need to call switchToXXXAdmin from either SFSB, the problem is, the xxx variable is always shown as null when



            pages.xml


            <page view-id="/fundAdmin.xhtml">     
                 <navigation from-action="#{fundAdmin.view(fund)}">          
                    <begin-conversation join="true"/>                           
                 </navigation>  
                 <navigation from-action="#{fundAdmin.save || fundAdmin.update || fundAdmin.delete}">    
                     <end-conversation/>      
                 </navigation> 
                 <navigation from-action="#{fundAdmin.switchToFofAdmin(fof)}">    
                    <redirect view-id="/fofAdmin.xhtml"/>
                 </navigation>      
              </page>
              
              <page view-id="/fofAdmin.xhtml">     
                  <navigation from-action="#{fofAdmin.view(fof)}">          
                    <begin-conversation join="true"/>                           
                  </navigation>  
                  <navigation from-action="#{fofAdmin.save || fofAdmin.update || fofAdmin.delete}">    
                     <end-conversation/>      
                  </navigation>   
                  <navigation from-action="#{fodAdmin.switchToFundAdmin(fund)}">    
                    <redirect view-id="/fundAdmin.xhtml"/>
                 </navigation>      
              </page>




            I've seen booking example, I dont recollect the above requirement though

            • 3. Re: how to pass variables between 2 SFSBs
              admin.admin.email.tld

              Here is a working example of what you asked for.  I modified the booking example (see find() method) to call a public method on an injected SFSB with a String param passed.  Default context for a SFSB is conversation scope.  enjoy.


              HotelSearchingAction.java


              package org.jboss.seam.example.booking;
              
              import java.util.List;
              
              import javax.ejb.Remove;
              import javax.ejb.Stateful;
              import javax.persistence.EntityManager;
              import javax.persistence.PersistenceContext;
              
              import org.jboss.seam.ScopeType;
              import org.jboss.seam.annotations.Factory;
              import org.jboss.seam.annotations.In;
              import org.jboss.seam.annotations.Name;
              import org.jboss.seam.annotations.Scope;
              import org.jboss.seam.annotations.datamodel.DataModel;
              import org.jboss.seam.annotations.security.Restrict;
              
              @Stateful
              @Name("hotelSearch")
              //@Scope(ScopeType.SESSION)
              @Restrict("#{identity.loggedIn}")
              public class HotelSearchingAction implements HotelSearching
              {
                 
                 @PersistenceContext
                 private EntityManager em;
                 
                 private String searchString;
                 private int pageSize = 10;
                 private int page;
                 
                 @DataModel
                 private List<Hotel> hotels;
                 
                 @In(create=true)
                 private TestLocal testAction;
                 
                 public void find()
                 {
                    page = 0;
                    queryHotels();
                    
                    //exec method on injected SFSB
                    testAction.calculate("100");
                 }
                 public void nextPage()
                 {
                    page++;
                    queryHotels();
                 }
                    
                 private void queryHotels()
                 {
                    hotels = em.createQuery("select h from Hotel h where lower(h.name) like #{pattern} or lower(h.city) like #{pattern} or lower(h.zip) like #{pattern} or lower(h.address) like #{pattern}")
                          .setMaxResults(pageSize)
                          .setFirstResult( page * pageSize )
                          .getResultList();
                 }
                 
                 public boolean isNextPageAvailable()
                 {
                    return hotels!=null && hotels.size()==pageSize;
                 }
                 
                 public int getPageSize() {
                    return pageSize;
                 }
                 
                 public void setPageSize(int pageSize) {
                    this.pageSize = pageSize;
                 }
                 
                 @Factory(value="pattern", scope=ScopeType.EVENT)
                 public String getSearchPattern()
                 {
                    return searchString==null ? 
                          "%" : '%' + searchString.toLowerCase().replace('*', '%') + '%';
                 }
                 
                 public String getSearchString()
                 {
                    return searchString;
                 }
                 
                 public void setSearchString(String searchString)
                 {
                    this.searchString = searchString;
                 }
                 
                 @Remove
                 public void destroy() {}
              }



              TestAction.java (new action class I created):


              //$Id: HotelSearchingAction.java 5579 2007-06-27 00:06:49Z gavin $
              package org.jboss.seam.example.booking;
              
              import javax.ejb.Remove;
              import javax.ejb.Stateful;
              
              import org.jboss.seam.ScopeType;
              import org.jboss.seam.annotations.Logger;
              import org.jboss.seam.annotations.Name;
              import org.jboss.seam.annotations.Scope;
              import org.jboss.seam.annotations.security.Restrict;
              import org.jboss.seam.log.Log;
              
              @Stateful
              @Name("testAction")
              @Scope(ScopeType.CONVERSATION)
              @Restrict("#{identity.loggedIn}")
              public class TestAction implements TestLocal
              {
                 
                 private String dollars;
                 
                 @Logger
                 Log log;
                   
                 public void calculate(String dollars) {
                      this.dollars = dollars;
                      log.info("dollars = "+dollars);
                 }
                 
                 @Remove
                 public void destroy() {}
              }

              • 4. Re: how to pass variables between 2 SFSBs
                pmuir

                Priya M wrote on Aug 08, 2008 03:13:

                EntityHome is full of bugs, doesn't work for all.


                What bugs, where are the JIRAs?

                • 5. Re: how to pass variables between 2 SFSBs
                  infinity2heaven

                  Sorry, my bad. I obviously know how this works.The problem was something else  --


                  I used <s:link action="#{sfsb.someMethod(variableB)}" />


                  and s:link doesnt pass variableB to server side, hence it was never being passed in the first place. I'm using <h:commandLink instead, which now passed the variable.

                  • 6. Re: how to pass variables between 2 SFSBs
                    infinity2heaven

                    I wanted to raise a JIRA but - I dont know what the problem is! It just doesn't update. (create delete works). A couple of my colleagues had the same problem and no idea what the reason could be. The examples and docs are pretty st fwd too. Besides, extending EntityController I can still write minimal code. I  saw the source code for EntityHome, it doesn't do much except for join transactions (which are already present) and raise events (which I dont need for now).