I have a controller that is stateless which takes care of processing forms. This is defined as ApplicationScoped. On my page I have a form associated to a backing bean defined as a ViewScoped.
The error I got when I want to process the form:
serverError: class com.sun.faces.mgbean.ManagedBeanCreationException Unable to create managed bean myController. The following problems were found:
- The scope of the object referenced by expression #{myFormBean}, view, is shorter than the referring managed beans (myController) scope of application
In my form:
Name: <h:inputText value="#{myFormBean.name}" id="name" />
<h:commandButton value="Save Name" action="#{myController.processForm}">
<f:ajax render="nameResult" />
</h:commandButton>
Your name is <h:outputText value="#{myFormBean.name}" id="nameResult"/>
The controller:
@ManagedBean
@ApplicationScoped
public class MyController {
@ManagedProperty("#{myFormBean}")
private MyFormBean myBean;
public void processForm() {
System.out.println(myBean.getName());
// Save current name in session
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(
"name", myBean.getName());
}
}
The backing bean:
@ManagedBean
@ViewScoped
public class MyFormBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I could solve that by setting the controller as SessionScoped but it’s not a clean way since the controller is stateless, so I don’t need one controller for each session. One controller for the whole application should be sufficient.
I have a Spring MVC background, that’s why I am confused on how to do things with JSF 2.0
There is a flaw in your design. Your controller is not stateless at all. It has a property which is different for each request/view, namely the
myBean. If it was supported, then every new request/view would override the previously set one and the enduser will face the property value of a completely different enduser. This leads to problems in high concurrent situations.You need to make it request/view scoped instead of application scoped. Still then, I believe that you have to approach it completely different. You’re manually setting an attribute in the session scope in the action method instead of setting it as a property of an (injected) session scoped bean. How to solve it properly depends on the functional requirement which is not clear from the question.