File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes JSF and the fly likes Problem with initializing managed-property parameter Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » JSF
Bookmark "Problem with initializing managed-property parameter" Watch "Problem with initializing managed-property parameter" New topic
Author

Problem with initializing managed-property parameter

Adam Kronicki
Ranch Hand

Joined: Sep 01, 2009
Posts: 68
In my page I set a managed-property param with a value selected from selectOneMenu. The code is below.

This works but the problem is that it will only work if the selectOneMenu's value will actually change (so the event is launched and the button is re-rendered). If I want to use the first (default) value I need to change it to sth. else and then change again to the first one . If I just press the button without changing the selectOneMenu value, the parameter is null. Of course in my bean's @postConstruct method I initialize the indexBean.model.selected_id with the first value. Where should I initialise it so that it would also set the "selected" param at startup? (the values are generated from a database so it cannot be hard coded - must be java code).

EDIT: for further clarification I post a snippet of the faces-config.xml file:

Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16019
    
  20


If I want to use the first (default) value I need to change it to sth. else and then change again to the first one .


I do not understand what that means. Could you please explain?

Usually you will want to code "ajaxSingle="true"" on your a4j:support. Otherwise, the action will submit the entire form instead of just the changed control value. And fail if any of the submitted values does not pass validation.

@PostConstruct isn't really the best way to handle stuff like this. Generally, it's a good practice to have the requesting function invoke a method in the backing bean to load an existing record or create a new one, and initialize the bean's properties at that time. That does require injecting the editing bean to be injected into the requesting bean, however.

Your best bet is NOT to leave the control value pre-initialized to NULL, however. Set it to an actual valid default value before displaying the form.


Customer surveys are for companies who didn't pay proper attention to begin with.
Adam Kronicki
Ranch Hand

Joined: Sep 01, 2009
Posts: 68
Tim Holloway wrote:

If I want to use the first (default) value I need to change it to sth. else and then change again to the first one .
I do not understand what that means. Could you please explain?

The problem is that when the page loads the "selected" param has a null value. When an onchange event occurs at the SelectOneMenu it re-renders the button tag, ergo setting the param value to current indexBean.model.selected_id - this works. However if the user does not change the value of selectOneMenu (leaving it at the default first one) and clicks the button, the "selected" param won't be set and remains at null. So what I meant above is that in order to pass the first default selectOneMenu value to the "selected" param, the user must change the SelectOneMenu value to sth. else and than again to the first value - this would trigger the onchange event, the button is re-rendered and the param is set. It is obviously a bug and a undesired behavior. If I would find a way to initialize the parameter in Java with the first value of selectOneMenu it won't be the case.
Tim Holloway wrote:
@PostConstruct isn't really the best way to handle stuff like this. Generally, it's a good practice to have the requesting function invoke a method in the backing bean to load an existing record or create a new one, and initialize the bean's properties at that time. That does require injecting the editing bean to be injected into the requesting bean, however.

Ok this got me lost somehow. Where should I initialize my bean's fields and value if not in @PostConstruct annotations? The SelectOneMenu values are populated form a database, with some other input parameters - so where is the Java place to run the initialization code? Surely not the bean's constructor. I though @PostConstruct annotation was exactly for this purpose...

I added a snippet form the faces-config.xml file in the first post for further clarification.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16019
    
  20

Shift your viewpoint a little. The selectOneMenu exists only to display and update the backing property value. The value is what is important, not the selection. JSF will handle the selection if you handle the value.

Rarely do my CRUD pages exist in a vacuum. Generally, they get invoked from some other page, which typically has some sort of "Create" and "Edit" controls (often the "Edit" controls are buttons in a table display of multiple records).

Because there's so much overlapping functionality between creation of a new data object and editing of an existing one, I normally have the same backing bean and view for both operations. The backing bean is injected (as a managed property) into the "from" bean, and it typically will have logic like this in it:


In the widget editor backing bean, the beginCreate() method initializes the model widget to default values. Including the default value for the selectOneMenu control.

The beginEdit method is much like it, except that instead of default values, the indicated record is fetched and used.

In both cases, I normally set a create/edit mode switch. This allows the "Save" button to know whether to do an INSERT or UPDATE as well as altering the UI so that, for example, the primary key is not editable for existing records.

Note that, everything I've done here is POJO code except for the one line where I'm accessing a JSF table dataModel object. This is what JSF is all about.
Adam Kronicki
Ranch Hand

Joined: Sep 01, 2009
Posts: 68
Tim thank you for your support but I don't know if we are on the same page here. I try to understand what you are trying to get across but I don't see it relevant. I don't know when, where and how are should I call the methods you have posted... There is no insert, update or save mechanism in my page... Maybe it's my fault but I have a feeling that we are talking about 2 different problems. I will try to explain what my situation is as much detailed and careful as I can:

My problem here is quite simple. I have a very simple page (only the jsp code snippet that you in the first post- nothing more). It's and index page in the whole webapp - so this does not 'come form' any other page. The job is to initialize and populate the SelectOneMenu with values from database, and when the user selects a value he then clicks on a button and the selected value is passed by f:param tag to another page (and bean - the formBean). This all that it is to the situation. The problem I have is already described - the mechanism does not work if the selectOneMenu value is not changed - then f:param is null. I see 2 solutions here:
-find a way to initialize f:param with the default value of selectedOneMenu. So if the user does not 'touch' selectOneMenu element and clicks on the button straight a way a proper value is passed (not null).
-find another way to assign the selectOneMenu value to the f:param (the one I use now with a4j event support was suggested to my on another discussion board).

I hope I don't sound rude, ignorant or anything else, but I just don't see the correlation here...
Adam Kronicki
Ranch Hand

Joined: Sep 01, 2009
Posts: 68
Ok I solved my problem (I screwed up the intialisation in @PostConstruct method - obviously sth so simple must have been also a trivial mistake too trivial to notice). However Tim, your post suggest that I do sth. very wrong with the whole process and I don't get the picture you are trying to present here. So if it's not a problem I am interested (and grateful of course) in a clearer explanation...
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16019
    
  20

The disconnect may be because I missed a critical sentence in your initial question - and in the topic title. You referred to a "parameter" in a managed property.

Looking back at your faces-config, you're attempting to inject the value "param.selected" into formBean. You never defined a managed bean named "param". That can be expected to either throw an exception or inject a null value into the target.

As a general rule, request-scope objects are pretty useless in JSF. That's because JSF does postbacks and request scope objects for postbacks are created from scratch each time, so you lose previously-initialized data. Session scope or (JSF2) View scope can remedy that problem.

For what it's worth, unlike Struts, the "Form Bean" is the MVC Model. Not to be confused with the Persistency object model, which we don't recommend trying to implement as a Managed Bean. JSF doesn't separate into Form Beans and Actions the way Struts does. That's one of its virtues. Fewer classes to implement.

 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Problem with initializing managed-property parameter