Backing Bean Constructur Called Multiple Times
If the constructor of a backing bean is called multiple times during one single request, the reason might be that the backing bean has no scope annotation. I experienced this problem using CDI, but it might also be the case for JSF managed beans. I expected the default scope to be @RequestScoped, but as it turned out this is not the case. For CDI the default scope is @Dependent and for JSF it’s None – which seems to be basically the same:
- JSF: “None: Objects with this scope are not visible in any JSF page. When used in the configuration file, they indicate managed beans that are used by other managed beans in the application. Objects with none scope can use other objects with none scope.” (taken from java-samples.com)
- CDI: “In addition to the four built-in scopes, CDI features the so-called dependent pseudo-scope. This is the default scope for a bean which does not explicitly declare a scope type. An instances of a dependent bean is never shared between different clients or different injection points. It is strictly a dependent object of some other object. It is instantiated when the object it belongs to is created, and destroyed when the object it belongs to is destroyed.” (taken from docs.jboss.org/weld/)
Before using @RequestScoped for my backing bean, the following actions took place when calling a simple registration backing bean:
After the first request of a simple registration form:
...
constructor called
getUsername()
...
After filling out the fields username, password
passwordAgain and clicking the register button:
...
constructor called
getUsername()
constructor called
constructor called
getUsername()
constructor called
constructor called
getPassword()
constructor called
constructor called
getPasswordAgain()
constructor called
setUsername(Homer)
constructor called
setPassword(foobar)
constructor called
setPasswordAgain(foobar)
constructor called
Not only was the constructor called way to often, it was also called one more time after all fields had been set. This means that no fields made it to the database, because they were all empty. It took me hours just to realize that this was no persistence or hibernate problem… so keep this nasty default scope in mind and use some of the explicit scope annotations such as @RequestScoped.