-
1. Re: Error redirecting to natural conversation
pmuir Apr 2, 2008 1:11 PM (in response to mocha)Yes, this should probably work.
Can you file a JIRA issue, and attach reproduction steps or an example? Thanks!
-
2. Re: Error redirecting to natural conversation
skunk May 22, 2008 4:02 PM (in response to mocha)Hello All,
I am having a similar problem to this, but with only a single page. This page is an entity home page with the entity being selected based on a page parameter. I have set this page parameter to be the natural conversation id so that when a form is submitted on it, actions on the same SFSB are executed. This means if the user hits back and then visits the same page for a different object they will see that object and not the last one they looked at (I had problems with conversations continuing on out of the current page without natural conversations).
The problem is that when I run the action methods approveCcr() or rejectCcr() in the SFSB below, the user is redirected back to the same page with the natural conversation parameter set, but an error page is shown. The exception is:
14:42:59,289 ERROR [STDERR] May 22, 2008 2:42:59 PM com.sun.facelets.FaceletViewHandler handleRenderException SEVERE: Error Rendering View[/ccrs/ccr.xhtml] javax.el.ELException: /ccrs/ccr.xhtml: Error reading 'ccr' on type org.javassist.tmp.java.lang.Object_$$_javassist_2 at com.sun.facelets.compiler.TextInstruction.write(TextInstruction.java:48) ... Caused by: javax.ejb.NoSuchEJBException: Could not find stateful bean: 3lcw53-2i0tx7-fgjd4rnj-1-fgje8ndc-g at org.jboss.ejb3.cache.simple.SimpleStatefulCache.get(SimpleStatefulCache.java:390) at org.jboss.ejb3.cache.simple.SimpleStatefulCache.get(SimpleStatefulCache.java:375) at org.jboss.ejb3.stateful.StatefulInstanceInterceptor.invoke(StatefulInstanceInterceptor.java:61) ...
If I highlight the address in the browser and issue another get request, everything works fine and the object is freshly retrieved as desired its updated properties.
These Ccr objects aren't created through the /ccrs/ccr.xhtml view - the form on this page is to add objects of another type to the Ccr.ccrAudits collection. If I don't try and end the conversation before showing the view again the Ccr being shown doesn't have the updated collection, though it is the correct Ccr. (I have tried forcing the object to be updated with entityManager.refresh(this.ccr) at the end of the requested action method but hibernate gives an exception something along the lines of 'session not open'.)
Am I having the same problem as above (and can I help fix?) or have I created a different bug?
Thanks!
Dave/ccrs/ccr.xhtml
<h1>CCR - #{ccrHome.ccr.title}</h1> <p>Code: #{ccrHome.ccr.ccrCode}<br/> Status: <h:outputText value="#{(ccrHome.ccr.completed eq true) ? ' Completed' : ' Open'}" /><br/> Effective: #{ccrHome.ccr.effective}</p> <h2>Audit Trail</h2> <h:outputText value="No audit history exists." rendered="#{empty ccrHome.ccr.ccrAudits}" /> <ol> <ui:repeat value="#{ccrHome.ccr.ccrAudits}" var="ccrAudit"> <li>#{ccrAudit.ccrAuditAction.name} by   <s:link value="#{ccrAudit.contact.name}" view="/contacts/contact.xhtml"> <f:param name="contactId" value="#{ccrAudit.contact.id}" /> </s:link> on #{ccrAudit.timeStamp}</li> </ui:repeat> </ol> <h:form rendered="#{ccrHome.ccr.completed eq false}"> <fieldset> <legend>Approve or Reject this CCR</legend> <label for="ccrAuditDetails">Details</label> <h:inputTextarea value="#{ccrHome.ccrAudit.details}" id="ccrAuditDetails" /><br/> </fieldset> <h:commandButton action="#{ccrHome.approveCcr}" value="Approve CCR" class="submit" conversationName="ccrHomePage"> <!--<s:conversationPropagation type="end" />--> </h:commandButton> <h:commandButton action="#{ccrHome.rejectCcr}" value="Reject CCR" class="submit" conversationName="ccrHomePage"> <!--<s:conversationPropagation type="end" />--> </h:commandButton><br/> </h:form>
relevant pages.xml
<conversation name="ccrHomePage" parameter-name="ccrId" parameter-value="#{ccrHome.ccr.id}" /> <page view-id="/ccrs/ccr.xhtml" conversation="ccrHomePage"> <begin-conversation join="false" /> <!-- TODO Why is this needed? --> <navigation> <rule if-outcome="approved"> <redirect view-id="/ccrs/ccr.xhtml"> <param name="ccrId" value="#{ccrHome.ccr.id}" /> </redirect> </rule> <rule if-outcome="rejected"> <redirect view-id="/ccrs/ccr.xhtml"> <param name="ccrId" value="#{ccrHome.ccr.id}" /> </redirect> </rule> </navigation> </page>
CcrHomeBean.java
@Stateful @Name("ccrHome") public class CcrHomeBean implements CcrHome { @PersistenceContext EntityManager mudEntityManager; @RequestParameter Integer ccrId; Ccr ccr; CcrAudit ccrAudit; OrganisationName organisationName; OrganisationName organisationNameOrig; ... some getters/setters removed @Begin // ignore this, run from another page entirely. public String newOrganisationNameChange() { this.ccr.setCcrType(mudEntityManager.find(CcrType.class, 1)); this.organisationName.setOrganisation(this.organisationNameOrig.getOrganisation()); this.organisationName.setCcr(this.ccr); return "confirm"; } @End public String cancelCcr() { return "cancelled"; } @End(beforeRedirect=true) public String confirmCcr() { mudEntityManager.persist(this.ccr); this.ccrAudit.setTimeStamp(new Date()); mudEntityManager.persist(this.ccrAudit); mudEntityManager.persist(this.organisationName); return "confirmed"; } @End(beforeRedirect=true) public String approveCcr() { this.ccr.setCompleted(true); this.ccrAudit.setCcrAuditAction(mudEntityManager.find(CcrAuditAction.class, 5)); this.ccrAudit.setTimeStamp(new Date()); mudEntityManager.merge(this.ccr); mudEntityManager.persist(this.ccrAudit); return "approved"; } @End(beforeRedirect=true) public String rejectCcr() { this.ccrAudit.setCcrAuditAction(mudEntityManager.find(CcrAuditAction.class, 4)); this.ccrAudit.setTimeStamp(new Date()); mudEntityManager.persist(this.ccrAudit); return "rejected"; } //@PostConstruct TODO - why doesn't this work? @Create public void initialize() { if(this.ccrId==null) { this.ccr = new Ccr(); this.ccr.setCompleted(false); this.ccrAudit = new CcrAudit(); this.ccrAudit.setContact(mudEntityManager.find(Contact.class, 1)); this.ccrAudit.setCcrAuditAction(mudEntityManager.find(CcrAuditAction.class, 1)); this.ccrAudit.setCcr(this.ccr); // TODO - line below needs to be generalised for different types of ccr this.organisationName = new OrganisationName(); } else { this.ccr = mudEntityManager.find(Ccr.class, this.ccrId); // TODO - the next few lines are probably not the correct way of doing this - waste of objects. // Should probably use @In(required=false) and set up the ccr relation at persist time. if (!this.ccr.getCompleted()) { // If the CCR is completed the GUI won't let them add changes or audit trail info anyway. this.ccrAudit = new CcrAudit(); this.ccrAudit.setCcr(this.ccr); this.ccrAudit.setContact(mudEntityManager.find(Contact.class, 1)); } } } @Remove @Destroy public void destroy() {} }
Ccr.java
@Entity @Table(name="ccrs") public class Ccr { private Integer id; private String title; private String ccrCode; private Boolean completed; private Date effective; private CcrType ccrType; private Collection<CcrAudit> ccrAudits; @Id @GeneratedValue @Column(name="ccr_id") public Integer getId() {return id;} public void setId(Integer id) {this.id = id;} @Column(name="title") public String getTitle() {return title;} public void setTitle(String title) {this.title = title;} @Column(name="ccr_code") public String getCcrCode() {return ccrCode;} public void setCcrCode(String ccrCode) {this.ccrCode = ccrCode;} @Column(name="completed") public Boolean getCompleted() {return completed;} public void setCompleted(Boolean completed) {this.completed = completed;} @Column(name="effective") public Date getEffective() {return effective;} public void setEffective(Date effective) {this.effective = effective;} @ManyToOne @JoinColumn(name="ccr_type_id",referencedColumnName="ccr_type_id") public CcrType getCcrType() {return ccrType;} public void setCcrType(CcrType ccrType) {this.ccrType = ccrType;} @OneToMany(mappedBy="ccr") public Collection<CcrAudit> getCcrAudits() {return ccrAudits;} public void setCcrAudits(Collection<CcrAudit> ccrAudits) {this.ccrAudits = ccrAudits;} }