[jboss-user] [JBoss Seam] - Session context variable missing
gmarcus
do-not-reply at jboss.com
Sat Jun 9 18:18:25 EDT 2007
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
More information about the jboss-user
mailing list