I got some problems understanding the Conversation scope of Weld or CDI.
In my JSF Faclets page i call:
<f:metadata>
<f:event type="preRenderView" listener="#{viewBean.start}" />
</f:metadata>
The bean:
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
@Named
@ConversationScoped
public class ViewBean implements Serializable {
@Inject
private Conversation conversation;
public void start() {
if (conversation.isTransient()) {
System.out.println("START CONVERSATION");
conversation.begin();
}
}
Now every time I refresh my browser, a new Conversation is started. Is that the correct behaviour? So why is the conversation always transient? No exception is thrown. The beans.xml is created and empty:
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
Short answer: Yes, this is the correct behavior.
Long answer: A conversation represents a “unit of work”, which a such has to be demarcated explicitly. This is done with the explicit call of conversation.begin() – as you are doing already. Should you want to use the same conversation over more than one request, you have to propagate it – this is what you are not doing 🙂
When you propagate a conversation, a conversation-id is appended to the request. This tells the container which conversation is wanted. When you just hit the refresh button without a conversation-id in your request a new conversation is generated for each request.
From the documentation:
If you need to propagate it manually, just add the conversation-id to the request:
All that and much more is explained here.