I assume everyone who has ever used Seam 2, JSF 1.x and RichFaces 3 knows the concept of Seam conversations and RF3 ajax components (a4j:support, a4j:commandLink, a4j:commandButton, etc.). The use of RF3 controls and Seam conversations is quite straightforward. Put the RF3 control on the facelet page, handle some ajax actions in Seam component, at some time promote temporary conversation to long-running, and finally rerender required parts of JSF page. Everything works. No need to put conversation id somewhere provided you don't leave the JSF view (or do non-JSF request).

 

Today's applications mostly switched to CDI (Weld), JSF 2 and RichFaces 4. As expected some problems may occur during migration of programming techniques. One of them might disrupt the previous experience...

 

Check following facelets fragment - Seam2/JSF/RF3:

<h:form id="form">

  <a4j:commandButton 
    value="Begin conversation" 
    id="A"
    action="#{action.beginConversation}" />

  <a4j:commandButton
    value="Do action"
    id="B"
    action="#{action.doSomethingInContextOfLongRunningConversation}" />

</h:form>

 

Clicking button A - begins conversation (Action#beginConversation promotes temporary conversation to long-running). Then clicking button B - the conversation is automatically propagated. Note that we do no rerendering. However for the same facelets fragment running on Weld/JSF2/RF4 the conversation is not automatically propagated. This also applies to native JSF components (f:ajax). Where is the problem? CDI does not define built-in JSF page/view scope so that it cannot restore conversation id from this context (like Seam 2 does). It only relies on HTTP request parameter cid. To have it working you will have to...

 

1) Rerender the whole form (Weld will automatically append the conversation id to form's action attribute):

<h:form id="form">

   <a4j:commandButton 
    value="Begin conversation"
    id="A"
    action="#{action.beginConversation}"
    render="@form" />

  <a4j:commandButton
    value="Do action"
    id="B"
    action="#{action.doSomethingInContextOfLongRunningConversation}" />

</h:form>

 

 

 

2) Propagate conversation id manually:

<h:form id="form">
  
  <a4j:commandButton
      value="Begin conversation"
      id="A"
      action="#{action.beginConversation}"
      render="B" />
  
  <a4j:commandButton
     value="Do action"
     id="B"
     action="#{action.doSomethingInContextOfLongRunningConversation}">
       <f:param name="cid" value="#{javax.enterprise.context.conversation.id}"/>
  </a4j:commandButton>

</h:form>

 

See also org.jboss.weld.jsf.ConversationAwareViewHandler.