[jboss-user] [JBoss Seam] - Stale Session Objects ? DataModelSelection Problems

kryptontri do-not-reply at jboss.com
Mon Jul 24 13:22:13 EDT 2006


JBoss 4.0.4.GA
JBoss Seam 1.0.1 GA 

Hi

I am having issues dealing with 1 to many relationships and DataModelSelection, in that
session data i think, doesn't seem to be cleared, this issue happens sporadically, i am looking for a pattern to see when it fails.

Basically, I have a set of rate objects that i can add for a contractor's page

This is the vew
anonymous wrote : 
  | 
  |                 
  |                     
  |                         <c:choose>
  |                             <c:when test='${ratesPageManager.rates == null or ratesPageManager.rowCount == 0}'>
  |                                 Empty Rates
  |                             </c:when>
  |                             <c:otherwise>
  |                                  <h:dataTable value="#{ratesPageManager.rates}" var="item"  rendered="#{ratesPageManager.rowCount>0}" rowClasses="rvgRowOne,rvgRowTwo">
  |                                      <h:column>
  |                                       <f:facet name="header"><h:outputText value="Duration"/></f:facet>
  |                                       <h:outputText value="#{item.duration}"/>
  |                                     </h:column>
  |                                     <h:column>
  |                                       <f:facet name="header"><h:outputText value="Unit"/></f:facet>
  |                                       <h:outputText value="#{item.unit}"/>
  |                                     </h:column>
  |                                     <h:column>
  |                                       <f:facet name="header"><h:outputText value="Currency"/></f:facet>
  |                                       <h:outputText value="#{item.currency}"/>
  |                                     </h:column>
  |                                     <h:column>
  |                                       <f:facet name="header"><h:outputText value="Cost"/></f:facet>
  |                                       <h:outputText value="#{item.cost}"/>
  |                                     </h:column>
  |                                     <h:column>
  |                                         <f:facet name="header">Action</f:facet>
  |                                         <h:commandLink action="#{ratesPageManager.deleteRate}">Delete</h:commandLink>
  |                                     </h:column>
  | 
  |                                  </h:dataTable>
  |                             </c:otherwise>
  |                         </c:choose>
  | 
  |                     
  |                 
  | 
  |                 
  |                 
  |                 
  |                  <h:form>
  |                         
  |                             
  |                                 <h:outputLabel for="duration">Duration:</h:outputLabel>
  |                                 <h:selectOneMenu id="duration" value="#{rate.duration}"><f:selectItems value="#{ratesManager.durations}"/></h:selectOneMenu>
  |                                 <h:outputLabel for="unit">Unit:</h:outputLabel>
  |                                 <h:selectOneMenu id="unit" value="#{rate.unit}"><f:selectItems value="#{ratesManager.units}"/></h:selectOneMenu>
  |                                 <h:outputLabel for="currency">Currency:</h:outputLabel>
  |                                 <h:selectOneMenu id="currency" value="#{rate.currency}"><f:selectItems value="#{ratesManager.currencys}"/></h:selectOneMenu>
  |                                 <h:outputLabel for="cost">Cost:</h:outputLabel>
  |                                 <h:selectOneMenu id="cost" value="#{rate.cost}"><f:selectItems value="#{ratesManager.costs}"/></h:selectOneMenu>
  |                             
  |                             
  |                                 
  |                                     <h:commandButton value="Add Rate" action="#{ratesPageManager.addRate}" class="button"/> 
  |                                 
  |                             
  |                         
  |                         </h:form>
  |                   
  |                 
  |             
  | 

For the Session bean behind this

anonymous wrote : 
  | @Stateful
  | @Scope(ScopeType.SESSION)
  | @Name("ratesPageManager")
  | @Interceptors(SeamInterceptor.class)
  | @LoggedIn
  | public class RatesPageManagerBean implements RatesPageManager {
  | 
  |     private static final Log log = LogFactory.getLog(RatesPageManagerBean.class.getName());
  | 
  |     @In
  |     @Out
  |     @Valid
  |     private User user;
  | 
  |     @In
  |     @Out
  |     @Valid
  |     private Profile profile;
  | 
  |     @In(required = false)
  |     @Out
  |     @Valid
  |     private RatesPage ratesPage;
  | 
  |     @PersistenceContext
  |     private EntityManager em;
  | 
  |     @In
  |     private transient FacesContext facesContext;
  | 
  |     @DataModel
  |     private List rates = new ArrayList();
  | 
  |     @Out(required=false)
  |     @DataModelSelection
  |     private Rate selectedRate;
  | 
  |     @In(required = false, create = true)
  |     @Out(required=false)
  |     private Rate rate;
  | 
  |     public Rate getRate() {
  |         return rate;
  |     }
  | 
  |     public void setRate(Rate rate) {
  |         this.rate = rate;
  |     }
  | 
  |     @IfInvalid(outcome = REDISPLAY)
  |     public String create() {
  |         if (profile.getRatesPage() == null) {
  |             em.persist(ratesPage);
  |             profile.setRatesPage(ratesPage);
  |             profile = em.merge(profile);
  |             return "viewRatesPage";
  |         } else {
  |             facesContext.addMessage(null, new FacesMessage("RatesPage already exists"));
  |             return "viewProfile";
  |         }
  |     }
  | 
  |     public String select() {
  |         profile = user.getProfile();
  |         ratesPage = profile.getRatesPage();
  |         rates.clear();
  |         rates.addAll(ratesPage.getRates());
  |         clearRatesOnDisplay();
  |         return "viewRatesPage";
  |     }
  | 
  | 
  |     private boolean isUnSet(Rate rateToCheck) {
  | 
  |         boolean isOk =  (
  |                         (rateToCheck.getCost() == 0) || (rateToCheck.getCurrency().equals("-")) ||
  |                         (rateToCheck.getDuration() == 0) || (rateToCheck.getUnit().equals("-"))
  |                         );
  |         log.info("Rate check:: cost=" + rateToCheck.getCost() + " currency=" +rateToCheck.getCurrency()
  |                  + " duration=" + rateToCheck.getDuration() + " unit=" + rateToCheck.getUnit());
  |         return isOk;
  |     }
  | 
  | 
  |     public String addRate() {
  |         log.info("addRate() called");
  | 
  |         if(isUnSet(rate)) {
  |             log.warn("Failed rates check");
  |              rate = null;
  |             facesContext.addMessage(null, new FacesMessage("Please enter rates"));
  |             return "viewRatesPage";
  |         }
  |          log.info("trying to add rate ..");
  |         rate.setRatesPage(ratesPage);
  |         em.persist(rate);
  |         ratesPage.addRate(rate);
  |         ratesPage = em.merge(ratesPage);
  |         profile = em.merge(profile);
  |         log.info("Persisted! and trying to remove");
  |         clearRatesOnDisplay();
  |         return select();
  |     }
  | 
  |     public String deleteRate() {
  |         log.info("deleteRate() called, removing " + selectedRate);
  |         rates.remove(selectedRate);
  |         ratesPage.removeRate(selectedRate);
  |         em.remove(selectedRate);
  |         clearRatesOnDisplay();
  |         return "viewRatesPage";
  |     }
  | 
  |     public List getRates() {
  |         log.info("getRates() called size = " +  this.rates.size());
  |         return this.rates;
  |     }
  |     public void setRates(List in) {
  |         this.rates = in;
  |     }
  |     public int getRowCount() {
  |         return this.rates.size();
  |     }
  | 
  | 
  | 
  |     public String delete() {
  |         profile.setGalleryPage(null);
  |         em.remove(ratesPage);
  |         profile = em.merge(profile);
  |         return "viewProfile";
  |     }
  | 
  |     @IfInvalid(outcome = REDISPLAY)
  |     public String edit() {
  |         ratesPage = em.merge(ratesPage);
  |         return "viewRatesPage";
  |     }
  | 
  |     @Destroy
  |     @Remove
  |     public void destroy() {
  |     }
  | 
  |     private void clearRatesOnDisplay() {
  |         Contexts.getPageContext().remove("rate");
  |         rate = null;
  |         selectedRate = null;
  |     }
  | 

The rate object which forms the many side of the relationship
anonymous wrote : 
  | @Entity
  | @Name("rate")
  | @Scope(SESSION)
  | public class Rate implements Serializable {
  | 
  |     protected int Id = 0;
  | 
  |     protected int duration = 0;
  |     protected String unit = null;
  |     protected String currency = null;
  |     protected int cost = 0;
  |     protected RatesPage ratesPage = null;
  | 
  |     @Id
  |     @GeneratedValue(strategy = GenerationType.AUTO)
  |     public int getId() {
  |         return Id;
  |     }
  | 
  |     public void setId(int id) {
  |         Id = id;
  |     }
  | 
  |     @NotNull
  |     public int getDuration() {
  |         return duration;
  |     }
  | 
  |     public void setDuration(int duration) {
  |         this.duration = duration;
  |     }
  | 
  |     @NotNull
  |     public String getUnit() {
  |         return unit;
  |     }
  | 
  |     public void setUnit(String unit) {
  |         this.unit = unit;
  |     }
  | 
  |     @NotNull
  |     public String getCurrency() {
  |         return currency;
  |     }
  | 
  |     public void setCurrency(String currency) {
  |         this.currency = currency;
  |     }
  | 
  |     @NotNull
  |     public int getCost() {
  |         return cost;
  |     }
  | 
  |     public void setCost(int cost) {
  |         this.cost = cost;
  |     }
  | 
  |     @ManyToOne
  |     @JoinColumn(name = "RATES_PAGE_ID")
  |     public RatesPage getRatesPage() {
  |         return ratesPage;
  |     }
  | 
  |     public void setRatesPage(RatesPage ratesPage) {
  |         this.ratesPage = ratesPage;
  |     }
  | 
  |     public boolean equals(Object o) {
  |         if (this == o) return true;
  |         if (o == null || getClass() != o.getClass()) return false;
  | 
  |         final Rate rate = (Rate) o;
  | 
  |         if (Id != rate.Id) return false;
  |         if (cost != rate.cost) return false;
  |         if (duration != rate.duration) return false;
  |         if (currency != null ? !currency.equals(rate.currency) : rate.currency != null) return false;
  |         if (ratesPage != null ? !ratesPage.equals(rate.ratesPage) : rate.ratesPage != null) return false;
  |         if (unit != null ? !unit.equals(rate.unit) : rate.unit != null) return false;
  | 
  |         return true;
  |     }
  | 
  |     public int hashCode() {
  |         int result;
  |         result = Id;
  |         result = 29 * result + duration;
  |         result = 29 * result + (unit != null ? unit.hashCode() : 0);
  |         result = 29 * result + (currency != null ? currency.hashCode() : 0);
  |         result = 29 * result + cost;
  |         result = 29 * result + (ratesPage != null ? ratesPage.hashCode() : 0);
  |         return result;
  |     }
  | 
  |     public String toString() {
  |         StringBuffer buffer = new StringBuffer();
  |         buffer.append("Id=").append(Id);
  |         buffer.append(" Duration=").append(duration);
  |         buffer.append(" Unit=").append(unit);
  |         buffer.append(" Currency=").append(currency);
  |         buffer.append(" Cost=").append(cost);
  |       //  buffer.append(" RatesPageId=").append(ratesPage.getId());
  |         return buffer.toString();
  |     }
  | 
  | }
  | 
  | 

What happens is that the debug server log will show an old rate, perhaps the
previous one add or that exists in the session and displays

anonymous wrote : 
  | 2006-07-24 18:07:50,055 DEBUG [org.jboss.seam.Component] selected row: Id=39 Duration=1 Unit=Week Currency=$ Cost=150
  | 

I added the clearRatesOnDisplay method to nullify any existence of state, in
an attempt to ensure that the select menus in the view are cleaned.

Any ideas people?

TIA Krypt


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

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



More information about the jboss-user mailing list