Conversation and ajax4jsf problem
bogdanminciu.bogdan.minciu.yahoo.com Mar 19, 2008 1:48 PMHello guys and girls,
I have this bean that is backing a blog entry add form:
@Stateful @Name("blogEntryCreate") @Scope(ScopeType.CONVERSATION) @Restrict("#{identity.loggedIn}") public class BlogEntryCreateBean implements LocalBlogEntryCreate { private String body; @In(create=true) @Out private List<Tag> attachedTags; @Logger private Log log; @Remove public void destroy() { } @Factory(value="attachedTags", autoCreate=true) public List<Tag> initTags() { log.info("initAttachedTags for #0", this); return new ArrayList<Tag>(); } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public void attachTag(Tag tag) { log.info("BlogEntryCreateBean.attachTag: attaching tag: #0", tag); if (!getAttachedTags().contains(tag)) { getAttachedTags().add(tag); log.info("#0 attached", tag); } } public void detachTag(Tag tag) { log.info("BlogEntryCreateBean.detachTag: detaching tag: #0", tag); if (getAttachedTags().contains(tag)) { getAttachedTags().remove(tag); log.info("#0 detached", tag); } } public List<Tag> getAttachedTags() { return attachedTags; } public void setAttachedTags(List<Tag> attachedTags) { this.attachedTags = attachedTags; } }
As you can see it is stateful and scoped to CONVERSATION. It works perfectly when adding the body of the blog entry, the new blog entry is saved into the database.
The problem is that this bean is created for each new tag added.
The xhtml backed by this bean is here:
... <a:outputPanel id="availableTags"> <div class="section"> Available tags(click to attach...): <h:outputText value="No Tags Found" rendered="#{tags==null or tagList.tags.size==0}"/> <h:form id="attachTag"> <ui:repeat id="repeatAvailableTags" value="#{tagList.tags}" var="tag" rendered="#{tags!=null and tagList.tags.size!=0}"> <a:commandLink id="attachTagA" action="#{blogEntryCreate.attachTag(tag)}" reRender="addedTags" value="#{tag.text}"/>  </ui:repeat> </h:form> </div> </a:outputPanel> <a:outputPanel id="addedTags"> <div class="section"> Attached tags(click to detach...): <h:outputText value="No Tags Found" rendered="#{blogEntryCreate.attachedTags==null or blogEntryCreate.attachedTags.size()==0}"/> <h:form id="detachTag"> <ui:repeat id="repeatAddedTags" value="#{blogEntryCreate.attachedTags}" var="tag"> <a:commandLink id="detachTagA" action="#{blogEntryCreate.detachTag(tag)}" reRender="addedTags" value="#{tag.text}"/>  </ui:repeat> </h:form> </div> </a:outputPanel> ...
As you can see i handle attaching/detaching of tags via ajax. The method calls are as expected, but the problem is that for each attachTag() method call, a new BlogEntryCreateBean instance is created. This is the output for the log:
14:44:24,203 INFO [BlogEntryCreateBean] initAttachedTags for com.brit.xcms.blog.BlogEntryCreateBean@75b3b6 14:44:33,703 INFO [BlogEntryCreateBean] initAttachedTags for com.brit.xcms.blog.BlogEntryCreateBean@9112ad 14:44:33,750 INFO [BlogEntryCreateBean] BlogEntryCreateBean.attachTag: attaching tag: hardware 14:44:33,750 INFO [BlogEntryCreateBean] hardware attached 14:44:34,765 INFO [BlogEntryCreateBean] initAttachedTags for com.brit.xcms.blog.BlogEntryCreateBean@598587 14:44:34,828 INFO [BlogEntryCreateBean] BlogEntryCreateBean.attachTag: attaching tag: software 14:44:34,828 INFO [BlogEntryCreateBean] software attached 14:44:38,031 INFO [BlogEntryCreateBean] initAttachedTags for com.brit.xcms.blog.BlogEntryCreateBean@9a8e52 14:44:38,078 INFO [BlogEntryCreateBean] BlogEntryCreateBean.attachTag: attaching tag: sport 14:44:38,078 INFO [BlogEntryCreateBean] sport attached
Where did I went wrong? Isn't the CONVERSATION scope enough for this type of calls? Why is a new instance of my bean created each time ajax calls its methods?
Thank you for any hint on this issue,
Bogdan.