Java Mailing List Archive

http://www.junlu.com/

Home » Home (12/2007) » JBoss User Help »

[jboss-user] [JBoss Seam] - Session context variable missing

scott.stark@jboss.org

2007-06-09


I have an Entitiy called Category as defined here:

| package com.mystuff.fresh.domain;
|
| import static org.jboss.seam.ScopeType.SESSION;
| import static org.jboss.seam.ScopeType.CONVERSATION;
|
| import java.io.Serializable;
|
| import javax.persistence.Entity;
| import javax.persistence.GeneratedValue;
| import javax.persistence.Id;
| import javax.persistence.NamedQueries;
| import javax.persistence.NamedQuery;
| import javax.persistence.Transient;
|
|
| import org.jboss.seam.annotations.Name;
| import org.jboss.seam.annotations.Role;
| import org.jboss.seam.annotations.Scope;
|
|
| @Entity
| @Name("category")
| @Scope(CONVERSATION)
| @Role(name = "currentCategory", scope=SESSION)
| @NamedQueries( {
|  @NamedQuery(name = "Category.findById", query = "SELECT c FROM Category c WHERE c.id=:id"),
|  @NamedQuery(name = "Category.findAll", query = "SELECT c FROM Category c"),
|  @NamedQuery(name = "Category.findRoot", query = "SELECT c FROM Category c WHERE c.id=0"),
|  @NamedQuery(name = "Category.findByName", query = "SELECT c FROM Category c WHERE toupper(c.name)=toupper(:name)")})
| public class Category implements Serializable
| {
|  private static final long serialVersionUID = 1881413500711441952L;
|
|  @Id
|  @GeneratedValue
|  private long id;
|
|  // parent category
|  private long parentId;
|
|  private String name;
|
|  private String description;
|
|  private long numberOfEntries;
|
|  // TODO: keep a view count on categories to know which are the most popular
|  // private long numViews;
|
|  private Boolean visible;
|
|
|  public Category()
|  {
|  }
|
|  /**
|   * @return the description
|   */
|  public String getDescription()
|  {
|    return description;
|  }
|
|  /**
|   * @param description
|   *        the description to set
|   */
|  public void setDescription(String description)
|  {
|    this.description = description;
|  }
|
|  /**
|   * @return the id
|   */
|  public long getId()
|  {
|    return id;
|  }
|
|  /**
|   * @param id
|   *        the id to set
|   */
|  public void setId(long id)
|  {
|    this.id = id;
|  }
|
|  /**
|   * @return the name
|   */
|  public String getName()
|  {
|    return name;
|  }
|
|  /**
|   * @param name
|   *        the name to set
|   */
|  public void setName(String name)
|  {
|    this.name = name;
|  }
|
|  /**
|   * @return the numberOfEntries
|   */
|  public long getNumberOfEntries()
|  {
|    return numberOfEntries;
|  }
|
|  /**
|   * @param numberOfEntries
|   *        the numberOfEntries to set
|   */
|  public void setNumberOfEntries(long numberOfEntries)
|  {
|    this.numberOfEntries = numberOfEntries;
|  }
|
|  /**
|   * @return the parentId
|   */
|  public long getParentId()
|  {
|    return parentId;
|  }
|
|  /**
|   * @param parentId
|   *        the parentId to set
|   */
|  public void setParentId(long parentId)
|  {
|    this.parentId = parentId;
|  }
|
|  /**
|   * @return the visible
|   */
|  public Boolean getVisible()
|  {
|    return visible;
|  }
|
|  /**
|   * @param visible
|   *        the visible to set
|   */
|  public void setVisible(Boolean visible)
|  {
|    this.visible = visible;
|  }
|
|  /**
|   * @return Boolean
|   */
|  @Transient
|  public Boolean isVisible()
|  {
|    return getVisible();
|  }
|
|  @Override
|  public String toString()
|  {
|    return ("Category(id:" + id + ", parentId:" + parentId + ", name:" + name + ", description:" + description + ", numberOfEntries:" + numberOfEntries + ", visible:" + visible + ")");
|  }
|
| }
|

I have a SFSB defined here:

| package com.mystuff.fresh.actions;
|
| import static javax.persistence.PersistenceContextType.EXTENDED;
|
| import java.util.List;
|
| import javax.ejb.Remove;
| import javax.ejb.Stateful;
| import javax.persistence.EntityManager;
| import javax.persistence.PersistenceContext;
|
| import org.jboss.seam.annotations.Create;
| import org.jboss.seam.annotations.Destroy;
| import org.jboss.seam.annotations.Factory;
| import org.jboss.seam.annotations.In;
| import org.jboss.seam.annotations.Logger;
| import org.jboss.seam.annotations.Name;
| import org.jboss.seam.annotations.Out;
| import org.jboss.seam.annotations.datamodel.DataModel;
| import org.jboss.seam.annotations.datamodel.DataModelSelection;
| import org.jboss.seam.log.Log;
|
| import com.mystuff.fresh.domain.Category;
| import com.mystuff.fresh.services.CategoryManager;
|
| @Stateful
| @Name("categoryManager")
| public class CategoryManagerAction implements CategoryManager
| {
|  @SuppressWarnings("unused")
|  @DataModel
|  private List<Category> categories;
|
|  @DataModelSelection
|  @In(required = false, create = false)
|  @Out(required = false)
|  private Category currentCategory;
|
|  @Out(required = false)
|  Category rootCategory;
|
|  @PersistenceContext(type = EXTENDED)
|  private EntityManager em;
|
|  @Logger
|  private static Log log;
|
|  @Factory("rootCategory")
|  public String findRoot()
|  {
|    log.trace("findRoot() called");
|    rootCategory = (Category) em.createNamedQuery("Category.findRoot").getSingleResult();
|    return "success";
|  }
|
|  @SuppressWarnings("unchecked")
|  @Factory("categories")
|  public String findCategories()
|  {
|    log.trace("findAll() called");
|    categories = em.createNamedQuery("Category.findAll").getResultList();
|    return "success";
|  }
|
|  // TODO: Need to find a way to initialize currentCategory at startup of the
|  // session so that
|  // It is available before any page loads. This is a current issue with the
|  // home.xhtml
|  // which wants to display the current category before referencing categories
|  @Create
|  public String init()
|  {
|    log.trace("init() called");
|
|    if (currentCategory == null)
|    {
|      log.warn("init() currentCategory is NULL");
|      currentCategory = (Category) em.createNamedQuery("Category.findRoot").getSingleResult();
|    }
|
|    log.info("init() - currentCategory: #0", currentCategory);
|    return "success";
|  }
|
|  public void select()
|  {
|    return;
|  }
|
|  @Remove
|  @Destroy
|  public void destroy()
|  {
|  }
| }
|

On the homepage, I want to display the list of Categories, with the currentCategory displayed with a graphic (a bullet) next to it:

home.xhtml

| <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
| <ui:composition xmlns="http://www.w3.org/1999/xhtml"
|           xmlns:s="http://jboss.com/products/seam/taglib"
|           xmlns:ui="http://java.sun.com/jsf/facelets"
|           xmlns:f="http://java.sun.com/jsf/core"
|           xmlns:h="http://java.sun.com/jsf/html"
|           template="/layout/template.xhtml">
|
| <ui:define name="body">
|
|   <h:messages globalOnly="true" styleClass="message"/>
|   <h:outputText value="CurrentCategory: #{currentCategory.name}"/>
|
|  <table class="standard">
|    <tr>
|      <td width="18%">
|        <ui:include src="/layout/categories.xhtml"/>
|      </td>
|    </tr>
|  </table>
|
|  
|  
| </ui:define>
| </ui:composition>
|

which includes the following xhtml snippet:
categories.xhtml

| <div class="category"
|    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">
| <h:form id="categorylistform">
| <h:outputText value="No categories to display" rendered="#{categories.rowCount==0}"/>
| <h:dataTable styleclass="category" value="#{categories}" var="cat" rendered="#{categories.rowCount>0}">
|   <h:column>
|    <h:graphicImage styleClass="vcenter" id="selectedcategoryimage" alt="selected category" url="/img/pic_selected_dot_9x9.gif" rendered="#{cat.id==currentCategory.id}"/>
|    </h:column>
|   <h:column>
|      <h:commandLink styleClass="topcategory" value="#{cat.name}" title="#{cat.description}" action="#{categoryManager.select}" rendered="#{cat.parentId == rootCategory.id}"/>
|      <h:commandLink styleClass="childcategory" value="#{cat.name}" title="#{cat.description}" action="#{categoryManager.select}" rendered="#{cat.parentId != rootCategory.id}"/>
|      <h:outputText value="??????(#{cat.numberOfEntries})"/>
|   </h:column>
| </h:dataTable>
| </h:form>
| </div>
|

here is a sample of the data loaded by import.sql:

| insert into Category (id, parentId, name, description, visible, numberOfEntries) values (0, 0, 'All', 'All description', true, 0)
| insert into Category (id, parentId, name, description, visible, numberOfEntries) values (1, 0, 'Arts', 'Arts description', true, 0)
| insert into Category (id, parentId, name, description, visible, numberOfEntries) values (2, 1, 'Art', 'Arts | Art description', true, 0)
| insert into Category (id, parentId, name, description, visible, numberOfEntries) values (3, 1, 'Books', 'Arts | Books description', true, 2)
| insert into Category (id, parentId, name, description, visible, numberOfEntries) values (4, 1, 'Movies', 'Arts | Movies description', true, 0)
| insert into Category (id, parentId, name, description, visible, numberOfEntries) values (5, 1, 'Music', 'Arts | Music description', true, 0)
| insert into Category (id, parentId, name, description, visible, numberOfEntries) values (6, 1, 'Television', 'Arts | Television description', true, 0)
| insert into Category (id, parentId, name, description, visible, numberOfEntries) values (7, 1, 'Theater', 'Arts | Theater description', true, 0)
| insert into Category (id, parentId, name, description, visible, numberOfEntries) values (8, 0, 'Business', 'Business description', true, 0)
|


Again, my goal is to remember what category the user has selected. I made currentCategory a SESSION scoped context variable. CategoryManagerAction is CONVERSATION component.

When I first load up home.xhtml, currentCategory is set to the Root Category result returned from entitymanager and the bullet appears next to the root category (All in this case).

When I click on a another category, the page refreshes and the bullet appears on the newly selected category (Books for example).

My issue is that if I refresh the page (using the browser refresh), the bullet disappears (I would expect it to be drawn next to Books).

If I hit refresh a second time, a bullet appears next to All.

It is as if the currentCategory is lost after the response is written. I checked debug.seam after clicking hitting refresh, and I see currentCategory in the SESSION, and it has the correct Book value.

Am I correct in defining currentCategory to be SESSION scoped in the entity, and setting it from the CONVERSATION scoped SFSB?

Is there a better way to organize this? Do I need @Factory("currentCategory") on a method on the SFSB to make this all work?



View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4052845#4052845

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4052845

_______________________________________________
jboss-user mailing list
jboss-user@(protected)
https://lists.jboss.org/mailman/listinfo/jboss-user
©2008 junlu.com - Jax Systems, LLC, U.S.A.