I have a backing bean as following:
@Named
@RequestScoped
public class ClientNewBackingBean {
@Inject
private ClientFacade facade;
private Client client;
The Client
class has a List<Child> childrenList
attribute, among others. I'm able to create a new Client
when setting the childrenList
with new ArrayList()
.
In the view, I have a input text field and an Add Child
button. The button has the attribute actionListener=#{clientNewBackingBean.addChild()}
implemented as:
public void addChild() {
if(client.getChildrenList() == null) {
client.getChildrenList(new ArrayList());
}
Child c = new Child("John Doe");
client.getChildrenList().add(c);
}
Everytime the Add Child
button is clicked, the bean is recreated and the view only shows one John Doe child (due to it being Request scoped, I believe). Is there another way to solve this besides changing the bean scope to Session?
If you were using standard JSF bean management annotation @ManagedBean
, you could have solved it by just placing the bean in the view scope by @ViewScoped
.
@ManagedBean
@ViewScoped
public class ClientNewBackingBean implements Serializable {
@EJB
private ClientFacade facade;
// ...
In CDI, the @ViewScoped
however doesn't exist, the closest alternative is @ConversationScoped
. You only have to start and stop it yourself.
@Named
@ConversationScoped
public class ClientNewBackingBean implements Serializable {
@Inject
private Conversation conversation;
// ...
@PostConstruct
public void init() {
conversation.begin();
}
public String submitAndNavigate() {
// ...
conversation.end();
return "someOtherPage?faces-redirect=true";
}
}
You can also use the CDI extension MyFaces CODI which will transparently bridge the JSF @ViewScoped
annotation to work properly together with @Named
:
@Named
@ViewScoped
public class ClientNewBackingBean implements Serializable {
@Inject
private ClientFacade facade;
// ...
A CODI alternative is to use @ViewAccessScoped
which lives as long as the subsequent requests reference the very same managed bean, irrespective of the physical view file used.
@Named
@ViewAccessScoped
public class ClientNewBackingBean implements Serializable {
@Inject
private ClientFacade facade;
// ...
See also:
- How to choose the right bean scope?
- Recommended JSF 2.0 CRUD frameworks
If you are using JSF 2, you should use ViewScoped
bean.