2
votes

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?

2

2 Answers

9
votes

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:

0
votes

If you are using JSF 2, you should use ViewScoped bean.