2 Replies Latest reply on Jan 26, 2008 9:50 PM by matt.drees

    Stateless bean holding data?

    oberiko

      Hello,

      I have two pages, edit and search. From the edit screen, the user can go to the search screen (which also contains a list). From the search/list screen, they can select an entity to edit.

      The problem is that my list, which is part of a stateless session bean, is being retained throughout trips to the search/list page. I.e., the previous search results are being shown after leaving and coming back.

      Is this the expected behaviour? My edit page is backed by a stateful session bean using the default conversation scope, so could that be throwing things off? Should I just add a "clearList()" call to my links from the search page to empty it as I leave?

      The code for the list page and its stateless session bean are below:

      package org.domain.myProject.session;
      
      import java.util.ArrayList;
      import java.util.List;
      
      import javax.ejb.Stateless;
      import javax.persistence.EntityManager;
      import javax.persistence.PersistenceContext;
      
      import org.domain.myProject.entity.Person;
      import org.domain.myProject.session.local.SearchPeopleLocal;
      import org.jboss.seam.annotations.In;
      import org.jboss.seam.annotations.Logger;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.faces.FacesMessages;
      import org.jboss.seam.framework.EntityQuery;
      import org.jboss.seam.log.Log;
      
      @Stateless
      @Name("searchPeople")
      public class SearchPeopleAction implements SearchPeopleLocal {
       @Logger
       private Log log;
      
       @In
       FacesMessages facesMessages;
      
       @PersistenceContext
       private EntityManager em;
      
       private List<Person> peopleList;
      
       @SuppressWarnings("unchecked")
       public void search() {
       /*
       * We are using an EntityQuery since it seems to be the quickest solution to
       * dynamic searches.
       */
       EntityQuery eq = new EntityQuery();
       eq.setEntityManager(em);
       eq.setEjbql("from Person p");
      
       /*
       * The EntityQuery can have restrictions (basically the "WHERE" part of the SQL)
       * placed on the returned results. Since they are (I believe) called remotely
       * from this class, we have to pass the 'seamComponent.parameter' (which is
       * the value that we'll be restricting on) in expression language
       */
       List<String> restrictions = new ArrayList<String>();
       restrictions.add("lower(p.name) like lower(concat('%',#{searchPeople.name},'%'))");
       eq.setRestrictions(restrictions);
      
       peopleList = eq.getResultList();
      
       if (peopleList.size() == 0)
       facesMessages.add("Search returned no results");
      
       log.info("Result list size is #0", log.info("Result list size is #0", peopleList.size());
       }
      
       // ************ The below variables (and their getters / setters) are used to make
       // ************ the dynamic query
       private String name;
      
       public String getName() {
       return name;
       }
      
       public void setName(String name) {
       this.name = name;
       }
      
       public List<Person> getPeopleList() {
       return peopleList;
       }
      
       public void setPeopleList(List<Person> peopleList) {
       this.peopleList = peopleList;
       }
      }
      


      <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:s="http://jboss.com/products/seam/taglib"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:h="http://java.sun.com/jsf/html">
      
      <f:view>
       <h:form>
       <h:inputText value="#{searchPeople.name}" />
       <h:commandButton action="#{searchPeople.search()}" value="Search" />
      
       <h:dataTable value="#{searchPeople.peopleList}" var="person"
       rendered="#{not empty searchPeople.peopleList}">
       <h:column>
       <f:facet name="header">
       <h:outputText value="Id" />
       </f:facet>
       <s:link value="#{person.id}" view ="/editPerson.xhtml">
       <f:param name ="personId" value="#{person.id}" />
       </s:link>
       </h:column>
       <h:column>
       <f:facet name="header">
       <h:outputText value="Name" />
       </f:facet>
       <h:outputText value="#{person.name}" />
       </h:column>
       <h:column>
       <f:facet name="header">
       <h:outputText value="Number of emails" />
       </f:facet>
       <h:outputText value="#{person.emailAddresses.size}" />
       </h:column>
       <h:column>
       <f:facet name="header">
       <h:outputText value="Actions" />
       </f:facet>
       </h:column>
       </h:dataTable>
       </h:form>
       <h:messages />
      </f:view>
      
      </html>
      


      If it's of any use, I can also post the code for the edit page and it's stateful session bean.

      Thanks!

        • 1. Re: Stateless bean holding data?
          blabno

          As far as I can see, the peopleList is updated only when search() method is called, so if you just get back to the listing page, then it accesses the same bean with old data. You could put action in pages.xml or in pageflow definition to be called before rendering the page.

          • 2. Re: Stateless bean holding data?
            matt.drees

             

            "Oberiko" wrote:

            
            @Stateless
            @Name("searchPeople")
            public class SearchPeopleAction implements SearchPeopleLocal {
            ...
             private List<Person> peopleList;
            
             public void search() {
            ...
             peopleList = eq.getResultList();
            ...
             }
            
             public List<Person> getPeopleList() {
             return peopleList;
             }
            
            }
            



            This isn't the right way to use a Stateless session bean. This is stateful behavior.

            So, what I'd do is make SearchPeopleAction an event-scoped stateful session bean.