9.2. Nested conversations
A nested conversation is created by invoking a method marked
@Begin(nested=true) within the scope of an existing conversation. A nested conversation has its own conversation context, but can read values from the outer conversation's context. The outer conversation's context is read-only within a nested conversation, but because objects are obtained by reference, changes to the objects themselves are reflected in the outer context.
- Nesting a conversation initializes a context that is stacked on the context of the original, or outer, conversation. The outer conversation is considered the parent.
- Values outjected or set directly into the nested conversation’s context do not affect the objects accessible in the parent conversation’s context.
- Injection, or a context lookup from the conversation context, first looks for the value in the current conversation context. If no value is found, lookup continues down the conversation stack, if the conversation is nested. This behavior can be overridden.
When an
@End is subsequently encountered, the nested conversation is destroyed, and the outer conversation resumes, popping the conversation stack. Conversations can be nested to any arbitrary depth.
Certain user activities (workspace management, or the back button) can cause the outer conversation to be resumed before the inner conversation ends. In this case, it is possible to have multiple concurrent nested conversations belonging to the same outer conversation. If the outer conversation ends before a nested conversation ends, Seam destroys all nested conversation contexts along with the outer context.
The conversation at the bottom of the conversation stack is the root conversation. Destroying this conversation always destroys all descendant conversations. You can achieve this declaratively by specifying
@End(root=true).
A conversation can be thought of as a continuable state. Nested conversations allow the application to capture a consistent continuable state at various points in a user interaction. This ensures correct behavior in the case of backbuttoning and workspace management.
As mentioned previously, if a component exists in a parent conversation of the current nested conversation, the nested conversation uses the same instance. Occasionally, it is useful to have a different instance in each nested conversation, so that the component instance of the parent conversation is invisible to its child conversations. You can achieve this behavior by annotating the component
@PerNestedConversation.