JSF ConversationScoped bean not elevating scope between POSTs

915 Views Asked by At

I have a bean with an action method called view() and a field of type MyObject:

@ManagedBean
@ConversationScoped
public class MyBean implements Serializable{
    private @Inject Conversation conversation; //has getter and setter
    private MyObject object; //has getter and setter
    ... other fields follow

    public String view(MyObject selectedObj){
        conversation.begin();
        return "success";
    }

    public String getSomeProperty(){
            return object.getProperty();
    }

    ...other methods follow
}

On screen1.xhtml I am using primefaces p:dataTable with var="obj" to output rows with a commandButton to view the object of the row the user clicks on. The button on each row looks like the following.

<p:commandButton action="#{myBean.view(obj)}"
ajax="false" title="View Clone" image="ui-icon ui-icon-locked"/>

When the user clicks on a commandButton in one of the rows, they are taken to page2.xhtml where more detailed info about the obj is displayed. This works correctly and displays the details. When I am inside of the view(MyObject selectedObj) action method, I immediately call conversation.begin(), assign this.obj = selectedObj, and user gets page2.xhtml.

However, when the user clicks a commandButton on page2 it should redisplay with different information from the obj that was assigned from the view() action call that happened when they came from page1 because the scope was elevated to conversation. This is not happening. The obj field is null in the bean when the scope should have prevented it from being lost. So when they clicked a commandButton on page2, it gives null pointer exception when the page tries to resolve #{myBean.someProperty}.

What am I missing? Thank you for any help.

2

There are 2 best solutions below

1
On

@ConversationScoped is an annotation of CDI. If you use it you must never use @ManagedBean which is a JSF annotation. instead you must annotate the bean with @Named.

0
On

@ConversationScoped is a feature of CDI, not JSF itself. That means that in order for it to work properly, you must use @ConversationScoped in combination with @javax.inject.Named, not @ManagedBean.

CDI is not by default included in JSF 2.0 or 2.1, so you would also need to add a CDI implementation like Weld (see http://seamframework.org/Weld) and an "empty beans.xml", as described in the weld documentation.