I'm currently evaluating Java EE 6 / JSF 2.1 with RichFaces.
A bean which is declared as
@ManagedBean
@ViewScoped
Since CDI beans don't have a ViewScope I tried to declare the bean as:
@Named
@ConversationScoped
Now the processing fails in step 3. because the value that was set in step 1 (checked that) is no longer available.
Do I have to use Conversation.begin()
and Conversation.end()
methods?
If so, where would be good place to invoke them?
If you can upgrade to JSF 2.2, immediately do it. It offers a native @ViewScoped
annotation for CDI.
import javax.faces.view.ViewScoped;
import javax.inject.Named;
@Named
@ViewScoped
public class Bean implements Serializable {
// ...
}
Alternatively, install OmniFaces which brings its own CDI compatible @ViewScoped
, including a working @PreDestroy
(which is broken on JSF @ViewScoped
).
import javax.inject.Named;
import org.omnifaces.cdi.ViewScoped;
@Named
@ViewScoped
public class Bean implements Serializable {
// ...
}
Another alternative is to install MyFaces CODI which transparently bridges JSF 2.0/2.1 @ViewScoped
to CDI. This only adds an autogenerated request parameter to the URL (like @ConversationScoped
would do).
import javax.faces.bean.ViewScoped;
import javax.inject.Named;
@Named
@ViewScoped
public class Bean implements Serializable {
// ...
}
If you really need to use @ConversationScoped
, then you indeed need to manually begin and end it. You need to @Inject
a Conversation
and invoke begin()
in the @PostConstruct
and end()
in the latest step of the conversation, usually an action method which redirects to a new view.
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Named;
@Named
@ConversationScoped
public class Bean implements Serializable {
@Inject
private Conversation conversation;
// ...
@PostConstruct
public void init() {
conversation.begin();
}
public String submit() {
// ...
conversation.end();
return "some.xhtml?faces-redirect=true";
}
}