Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

JSF immediate=true: Bug?

 
Gregg Bolinger
Ranch Hand
Posts: 15304
6
Chrome IntelliJ IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am running into a serious problem with immediate="true" and I am hoping someone knows a workaround.

I have a form and at the top of the form I have a inputText that takes in an employee id so I can find an employee and fill in part of the form. I have an actionListener bound to this component and I have immediate="true" because I don't want any validation to occur. Well, the problem is setting immediate="true" bypasses the UPDATE_MODEL phase and goes straight to the render phase. So when I try and get the employee ID that was entered in the textfield I get a NumberFormatException because the converter is trying to convert an empty string to a number.

I read that this was supposed to be fixed in the final RI but appearntly it is not. Does anyone have any insight into this?
 
Varun Khanna
Ranch Hand
Posts: 1400
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry I couldn't get your problem.


I have a form and at the top of the form I have a inputText that takes in an employee id so I can find an employee and fill in part of the form. I have an actionListener bound to this component and I have immediate="true" because I don't want any validation to occur.

Okey,

Well, the problem is setting immediate="true" bypasses the UPDATE_MODEL phase and goes straight to the render phase.

It bypasses the Process Validation phase, in your case is it bypassing the UPDATE_MODEL too ?


So when I try and get the employee ID that was entered in the textfield I get a NumberFormatException because the converter is trying to convert an empty string to a number.

Isn't it too late (after UPDATE_MODEL) for conversion stuff? Have you explicitly set the phase Id etc. or am I missing something?
Conversions are called in the APPLY Request phase, for immediate=true


I read that this was supposed to be fixed in the final RI but appearntly it is not. Does anyone have any insight into this?

Which RI are you using? This is working perfectly fine with me unless I am missing some point of yours.
 
Varun Khanna
Ranch Hand
Posts: 1400
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

So when I try and get the employee ID that was entered in the textfield I get a NumberFormatException because the converter is trying to convert an empty string to a number.

I doubt for an empty string or a null value the converted will be invoked.
 
Gregg Bolinger
Ranch Hand
Posts: 15304
6
Chrome IntelliJ IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, well, let me show some code.

newissue.jsp


NewIssueForm.java


I get a NumberFormatException (which is a faces exception) on the line:

Employee employee = new EmployeeDAO().getEmployee(new Long(getEmployeeId()));

If I set immediate="false" everything works perfectly as long as I remove validate from all my other components. Otherwise the Lookup button fires validation so the doSearch method is never called.

I hope that makes more sense.
 
Varun Khanna
Ranch Hand
Posts: 1400
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well I guess I got it ...
Please retain your immediate=true, and in the actionListener method just put this line at the bottom

FacesContext ftx = FacesContext.getCurrentInstance();
ftx.renderResponse();

This will ensure that nothing (validations etc.) is called after your actionListener is called.
[ December 15, 2004: Message edited by: K Varun ]
 
Varun Khanna
Ranch Hand
Posts: 1400
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Also please ensure that your actinListener is called in the Apply Request Values Phase.
 
Gregg Bolinger
Ranch Hand
Posts: 15304
6
Chrome IntelliJ IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, I tried what you suggested and it didn't work. I still get the same error message. I changed immediate to falsa and removed the validation from the other fields and it works great. But I need the validation.
 
Varun Khanna
Ranch Hand
Posts: 1400
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's looking logical now

Since in command button you have set immediate="true", the actionListener method "doSearch" is getting called in the APPLY_REQUEST phase. Now in the doSearch() method, you are using this code to get the employee id -->

Employee employee = new EmployeeDAO().getEmployee(new Long(getEmployeeId()));

now see that you are in the APPY_REQUEST phase, and by using
getEmployeeId() you are trying to get it from model bean, but the UPDATE_MODEL phase is still *not called*, hence the submitted employee id is *not yet* updated on the model bean and hence you are getting empty string and hence an exception.

Try to fire your event after UPDATE_MODEL phase, it should ("should" is safer than "will" in JSF 1.1 ) work fine.
 
Gregg Bolinger
Ranch Hand
Posts: 15304
6
Chrome IntelliJ IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by K Varun:
Try to fire your event after UPDATE_MODEL phase, it should ("should" is safer than "will" in JSF 1.1 ) work fine.


And how do I do that?
 
Varun Khanna
Ranch Hand
Posts: 1400
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Gregg Bolinger:


And how do I do that?


put your action method's code in the else block



P.S. I hope I didn't screwed up the starting/ending braces in the above text.
P.S.S. Please check out the debug messages to see if the event is fired in appropriate phase.
 
Gregg Bolinger
Ranch Hand
Posts: 15304
6
Chrome IntelliJ IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, I changed my doSearch method to the following:



And now I am getting an exception:



Any ideas? BTW..I really appreciate your helping me with this issue.
 
Varun Khanna
Ranch Hand
Posts: 1400
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can you show if any of the system.out were printed (Inside doSearch)?
or does this error popped-up prior to that code execution?


immediate=true prompts validator/actionlistner in APPY_REQUEST phase but we are forcing event listener to move to INVOKE_APPLICATION phase, I fear if JSF is stopping us from that.
 
Gregg Bolinger
Ranch Hand
Posts: 15304
6
Chrome IntelliJ IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
PhaseId: APPLY_REQUEST_VALUES(2)
 
Varun Khanna
Ranch Hand
Posts: 1400
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well if you are really interested in solving this problem, I am going to suggest you a real quick "dirty" hack

Get the ExternalContext reference in your doSearch() method :
ExternalContext etx =FacesContext.getCurrentInstance().getExternalContext();

Get the HttpRequest object from "etx"
//please check the ExternalContext api to see how to do this

//extract the employee id from request using
String id = (String)request.getParameter("employeeId");

//Now feel free to do use this "id"
Employee employee = new EmployeeDAO().getEmployee(new Long(id));

Surely, this is not going to give you any error and things will work fine, mainly because we are breaking the shackles of JSF.
And I did mentioned earlier and mentioning again : If our UI pages involves a lot of logic/processing/validation ... JSF isn't so good/simple as it sounds. I am facing this music since long now.

Lets hope SUN is going to do something real quick to resolve these issues
 
Gregg Bolinger
Ranch Hand
Posts: 15304
6
Chrome IntelliJ IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, I wish that worked. But it doesn't. I honestly don't think anything is even being put in the request when that method is called. This really sucks. For now, I am just turning validation off so I can continue.
 
Varun Khanna
Ranch Hand
Posts: 1400
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, I wish that worked. But it doesn't.



This should work as this is just a normal thing which have been doing since years. submit a page with a param and extract the param from HttpRequest.

My last minor suggestion for the day
When your page is displayed, just do the view source of the page and see what id your "employee Id" field is having and do the request.getParameter on that id (or check if your request Map is carrying that object).
And I am sure it's coming in your request since by setting immediate=false it's working.

Generally in JSF the "id" of the field is not just the "id" you set in, it comes out in the form of "formname:id". You can do the view source to check this and see if it works.
 
S Mishra
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Probably you can resolve your problem by doing any one of the two things:

1. Set the Emploee Id attribute's immediate="true" and call a valueChangeListener on it to first update its value in the model bean. Once it is done you will always get the value from the Managed Bean. Doing this will not call the Validations on other fields. Thats what I am doing in my application.

<h anelGroup>
<h:inputText required="true" id="employeeId"
value="#{newIssueForm.employeeId}"
styleClass="common-textbox"
valueChangeListener="#{newIssueForm.changeValue}"
onchange="submit();" immediate="true"/>
<h:commandButton immediate="true" styleClass="common-button" actionListener="#{newIssueForm.doSearch}" id="searchbutton" value="Search"/>
<h:message for="employeeId" styleClass="error-label"/>
</h anelGroup>


public void changeValue(ValueChangeEvent event) {
employeeId = (String) event.getNewValue();
}

2. You can try to get the value from the ValueHolder Interface. ValueHolder interface holds the local values of all UIComponents. You can try this out as I am not very sure of this technique.
 
Varun Khanna
Ranch Hand
Posts: 1400
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If immediate="true" can be put into the "employee id", then Option 1 does sounds like a good solution
 
Varun Khanna
Ranch Hand
Posts: 1400
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Gregg Bolinger:
Well, I wish that worked. But it doesn't. I honestly don't think anything is even being put in the request when that method is called. This really sucks. For now, I am just turning validation off so I can continue.


Here is what I tried to see if values are coming in my request:

And this was my output :

Object: on Key: ulValuesForm:_id240
Object: on Key: ulValuesForm:_id141
Object: div1 Key: ulValuesForm:chooseOption
Object: on Key: ulValuesForm:_id246
Object: ulValuesForm Key: ulValuesForm

My form name was ulValuesForm, and I added a hidden parameter in it :
<h:inputHidden id="chooseOption" value="div1" />
and you can see it's present in the request, though the key for it would be formname:id i.e. ulValuesForm:chooseOption
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic