1

Consider the following use case. I'm developing JSF form with @RequestScoped backing bean. Also, I use PrimeFaces, but it is not of much relevance to the problem.

Values in the form's fields are tied between each other with complex business logic. I.e. values in one dropdown depend on value in another dropdown, or enabled/disabled status of a field depends on the value in another field. And contents of table depends on view parameter or value in some hidden field.

Setters in the backing bean write values to the data model builder, and getters invoke the builder's build() method, which applies values in some predefined order and returns immutable data model.

@RequestScoped means that on postback (be it AJAX or regular request) the form's backing bean needs to be reconstructed from null. And it happens during UPDATE_MODEL_VALUES phase.

Troubles begin when we employ, e.g., selectOneMenu (JSF selectOneMenu or PrimeFaces selectOneMenu - doesn't matter) or dataTable. Because during PROCESS_VALIDATIONS phase (which takes place before UPDATE_MODEL_VALUES) the backing bean is still not set with values. Mentioned components fail built-in validations, because the request values doesn't correspond to any values from [still empty] Collection (serving content for selectOneMenu or dataTable or any like these).

One solution that I've figured out is to employ the backing bean's @PostConstruct method where we could manually read the necessary request values and pre-populate needed collections. But this solution is far from clean and elegant, it seems.

Also, I've tried to apply custom dummy validator, but it doesn't seem to substitute the built-in one, so this doesn't work.

What would be expert advice in this case, considering that I want to stick with @RequestScoped?

Thanks!

Tiny
  • 27,221
  • 105
  • 339
  • 599
iTollu
  • 999
  • 13
  • 20

1 Answers1

2

That's among others exactly why @ViewScoped exist.

Manually maintaining the view state in @PostConstruct of a @RequestScoped bean during every postback is best what you can do if you don't want to make use of JSF's "automatic" view state management via @ViewScoped. You can at most inject parameters via @ManagedProperty. The <f:viewParam>, which has validation/conversion support, is far from useful as it runs "too late".

In case you're using CDI managed beans, JSF utility library OmniFaces has a CDI @Param which supports validation and conversion too, on contrary to @ManagedProperty. This may further reduce boilerplate in @PostConstruct method.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thank you, @BalusC, `@Param` have done it! I pass `f:param` with `commandButton` and then set it in @PostConstruct. Also, I've got rid of `f:viewParam` and old jsf xml namespace, which has issues on some old Mojarra versions. – iTollu Aug 17 '15 at 10:15