Thursday, February 16, 2012

Cannot create Seam component, scope is not active


The problem:

I kept on running into to following error:
WARN  [org.jboss.seam.Component]  Cannot create Seam component, scope is not active: mySuperAction(CONVERSATION)
SEVERE [javax.enterprise.resource.webcontainer.jsf.lifecycle] JSF1054: (Phase ID: RESTORE_VIEW 1, View ID: /ThePage.xhtml) Exception thrown during phase execution: javax.faces.event.PhaseEvent[source=com.sun.faces.lifecycle.LifecycleImpl@19da36b]

Seam said my long-running conversation was gone.  But how could this be!  Well after a lot of digging I found this hidden line in the Seam documentation:

Conversational components have one minor limitation: they cannot be used to hold bindings to JSF components. 

What I was doing is I had a DataTable binding in the JSF.  The reason for this is I was not sure what columns or data was going to be displayed for the datatable until the time the page was being generated.

The solution:


As stated in the documentation, move and the HtmlPanelGrid in a new container with scope set to EVENT.
@Name("grid")
@Scope(ScopeType.EVENT)
public class Grid
{
    private HtmlPanelGrid htmlPanelGrid;

    // getters and setters
    ...
}@Name("mySuperAction")
@Scope(ScopeType.CONVERSATION)
public class MySuperAction
{
    @In(create=true)
    private Grid grid;
   
    private void populateTable(){....}

 }
Add to the page.xml a new action that calls the populateTable:
<action execute="#{mySuperAction.populateTable}" />
Now for the binding:
<h:panelGroup id="dynamicTablePanel" binding="#{grid.htmlPanelGrid}" />
Just as a note I found in a few forum posts where made where they stated adding getters and setters for the Grid on the MySuperAction thus making the binding look like this:

 <h:panelGroup id="dynamicTablePanel" binding="#{mySuperAction.grid.htmlPanelGrid}" />
This will work until you do your first AJAX call on the page and you will be hit with a nice RESTORE_VIEW error.

No comments:

Post a Comment