tags:

views:

157

answers:

1

I am using JSF 2.0 and attempting to pass values between different pages in my App.

The setup is as follows: I have a page called userSelect that has a backing bean userSelectBacking. On this page I display a list of users that can be selected and submit using an h:commandbutton, when the page is submit the navigation goes to a userEdit page.

I have a page called userEdit, that has a backing bean userEditBacking which displays the information for a user and allows that user to be edited.

I would like to pass the user selected from the userSelect page into the userEdit page. I am currently using f:setPropertyActionListener to set the user in my userEdit backing from the userSelect page, however when I navigate to the userEdit page, it loses the information I set.

is there a way that I can pass the values between the two pages/backing beans?

thanks

+1  A: 

I am currently using f:setPropertyActionListener to set the user in my userEdit backing from the userSelect page

It should work.

however when I navigate to the userEdit page, it loses the information I set.

This will happen if the data loading logic is wrong, or you fire a redirect afterwards while the bean is request scoped.

To fix the data loading logic, just ensure that in case of a request scoped bean the same datamodel is preserved in the subsequent request. Usually you use the bean's constructor or lazy loading in the getter for this. If that is not an option, then you need to put the bean in a bit broader scope, e.g. @ViewScope or @SessionScope.

To fix the redirect issue, either just don't fire a redirect (i.e. remove <redirect/> from navigation case, or don't call ExternalContext#redirect()), or put bean in a broader scope.

BalusC
Thanks! the redirect was indeed the problem!
kgrad
You're welcome.
BalusC
@BalusC - I have run into a new problem, when I try to edit the user entity in my userEdit page, even though it is displaying properly, I get an error that the entity is null. I am using value binding if it makes a difference. Do you have any reason why this would be?
kgrad
You need to preserve the entity or put the bean in a broader scope. Start with `@ViewScope`.
BalusC
What exactly do you mean by preserve the entity? I'm not sure what I should be setting my user to within the constructor... I was under the impression that it was being set dynamically by the setpropertyactionlistener... If you have a good tutorial that goes over this it would be much appreciated
kgrad
If the bean is request scoped you need to make sure that its constructor and getter returns exactly the same entity in the subsequent request. You know, a request scoped bean has a lifetime of only one HTTP request. It's garbaged immediately after completing the HTTP request (after sending the response). The request to display the list is one request. The request to edit the item is another request. The request to save the item is again another request. There's means of 3 independent bean instances. You've passed the entity from request 1 to 2, but not from 2 to 3.
BalusC
Thanks for the great explanation, the part I am still lost at is how to pass along that request if it disappears when it is displayed. My xhtml pages reference my backing bean to display their contents. I thought that the contents were value bound to my backing bean, if this is not the case, how do I access the contents from the xhtml page? I attempted to widen the scope to both view and session but neither of them worked. I think I am still missing a key piece of understanding, or I have something setup incorrectly. I have no idea if I am on the right track but I am now trying to use f:param
kgrad
@BalusC - I have been pouring over JSF info and I am still not understanding how the model object is null on form submit. From what I understand, the JSF Lifecycle should automatically update model values during the update model values portion of the lifecycle. I shouldn't have to do any manual plumbing... When I click the submit button it should automatically load the data in the form into my model entity...
kgrad
It will only set model values. It will not set the model itself. As a simple example: for `#{usermanager.user.address.street}` you need to define `usermanager` bean and preserve `user` and `address` models yourself. JSF will only set the `street`. E.g. it basically does `findBean("usermanager").getUser().getAddress().setStreet(value)`. You should always preserve the nested model objects yourself. I.e. `private User user = new User()` in `UserManager` bean.
BalusC
and `private Address address = new Address()` in the `User` bean... Or just re-obtain them all from the DAO during construction of `UserManager` and preserve it. Or put the bean in a bit broader scope, such as `@ViewScope` or `@SessionScope`.
BalusC
@BalusC - OK point understood, but then how can I use the value set with propertyActionListener to preserve my entity. The goal would be for example, to pass along the userId and then grab the user from the database using that id. I.e. in userSelect I get the userId, use f:setpropertyActionListener to call setUserId in usereditbacking, navigate to userEdit and then use that userId in my constructor for user: user = new User(userid).After the navigation, that value for userid is null, if i attempt to instantiate user using the id i get a null exception... even with viewscoped usereditbacking
kgrad