I have a JSF application in which I use JSF h:inputText for accepting user data. I bind the input fields to java objects using managed beans which is mostly normal.
The data entered in the HTML form is saved periodically using sequential ajax calls. Sometimes the periodic save fails with error in looking up the mapped object to the input field(the error message says it can not find the java object). This may not happen for the next call to save the data though nothing is changed in the application. I can't figure out the pattern to reproduce this bug. When I try to debug printing the object values it works fine too. In the input value mapping I have nested objects which I suspect may have something to do with the error.
Here is the code snippet in JSF page.
<c:forEach var="doc"
items="#{trim.trim.act.relationship['patientSurgeons'].act.relationshipsList['physician']}"
varStatus="physicianIndex">
<table>
<tr>
<td><h:inputText
id="firstName#{physicianIndex.index}" placeholder="first name"
value="#{doc.act.participation['surgeon'].role.player.name.EN['L'].parts[0].ST.value}"
class="sidebyside small" />
</td>
Here is how the exception stack trace
15:52:55,239 ERROR [[Faces Servlet]] Servlet.service() for servlet Faces Servlet threw exception
javax.el.PropertyNotFoundException: /META-INF/tags/wizard/inputTextWithPlaceholder.xhtml #15,86 value="#{value}": /wizard/questionnaireWiz/patientPhysicians.xhtml #73,36 value="#{doc.act.participation['surgeon'].role.player.name.EN['L'].parts[0].ST.value}": Target Unreachable, identifier 'doc' resolved to null
at com.sun.facelets.el.TagValueExpression.getType(TagValueExpression.java:62)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:81)
at javax.faces.component.UIInput.getConvertedValue(UIInput.java:934)
at javax.faces.component.UIInput.validate(UIInput.java:860)
at javax.faces.component.UIInput.executeValidate(UIInput.java:1065)
at javax.faces.component.UIInput.processValidators(UIInput.java:666)
at javax.faces.component.UIForm.processValidators(UIForm.java:229)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1033)
at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:662)
at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:100)
at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:244)
What could I be missing here?
This construct will fail like that when the value behind <c:forEach items> is not available during process validations phase of the postback request and hence #{doc} evaluates to null. For example, because the #{trim} is a request scoped bean whose data is initialized via a <f:viewParam>. Making it a view scoped bean (and in case you're using Mojarra, ensuring that you're using at least 2.1.18), should fix it.
Related
I have recently encountered a case where I wanted to set the index value from ui:repeat varStatus="v" using <h:inputHidden="#{v.index}/>. If you try this and execute the component using AJAX you will get an exception that the property is not writeable. While looking around I found that inputHidden supports a readonly="true" attribute that does just that making the error go away.
Is there a reason why this is not in documentation? (i.e. special, passthrough, other)
Is it safe to use?
After doing some digging Core JavaServer Faces 3e had this to say :
The h:inputHidden tag has the same attributes as the other input tags, except that it does not support the standard HTML and DHTML tags
So, the reason why readonly is not in the docs for inputHidden and also why it's not being rendered in your HTML is because inputHidden does not support it. This was also confirmed by Netbeans when I tried to add readonly as an attribute to inputHidden'(red squiggly lines with an error message). I was able to get that exception when I submitted a form with no setter defined for my bean property that was placed in inputHidden. Since inputHidden calls the setter when a form is submitted (for my case) and since none is defined in my code, it will of course throw that exception, namely:
javax.el.PropertyNotWritableException: /index.xhtml #14,56 value="#{bean.x}": The class 'Bean' does not have a writable property 'x'.
As for why it works when you do that I have no idea. Since you're worried about safety, I would suggest you do as BalusC says and simply use <input type="hidden"> or you define a setter for that property. Don't use it like that.
So long time since this question started, however just FYI, this works:
<h:inputHidden id="compId" readonly="#{true}" value="#{myBean.attribute}" />
I searched everywhere but could not find a solution to this. I am trying to used
required=yes to validate whether a value is present or not. I am using it inside inputtext.
The problem is it does not work inside a datatable. If I put the text box outside the datatable it works. I am using JSF 1.7 so I don't have the validateRequired tag from JSF 2.0.
I even used a validator class but it is still not working. Does anyone know why does required=yes or validator='validationClass' inside a inputtext inside a datatable is not working.
I appreciate the help.
Thanks.
First of all, the proper attribute values of the required attribute are the boolean values true or false, not a string value of Yes. It's an attribute which accepts a boolean expression.
The following are proper usage examples:
<h:inputText required="true" />
<h:inputText required="#{bean.booleanValue}" />
<h:inputText required="#{bean.stringValue == 'Yes'}" />
As to the problem that it doesn't work inside a <h:dataTable>, that can happen when the datamodel is not been preserved properly (the datamodel is whatever the table retrieves in its value attribute). That can in turn happen when the managed bean is request scoped and doesn't prepare the datamodel during its (post)construction which causes that the datamodel is null or empty while JSF is about to gather, convert and validate the submitted values.
You need to ensure that the datamodel is exactly the same during the apply request values phase of the form submit request as it was during the render response phase of the initial request to display the form with the table. An easy quick test is to put the bean in the session scope. If that fixes the problem, then you definitely need to rewrite the datamodel preserving logic. You could also use Tomahawk's <t:saveState> or <t:dataTable preserveDataModel="true"> to store the datamodel in the view scope (like as JSF2's new view scope is doing).
Finally, JSF 1.7 doesn't exist. Perhaps you mean JSF 1.2?
It appears that if you use a selectManyCheckbox backed by a set that is proxied by hibernate you will run into problems with the dreaded LazyInitializationException. This has nothing to do with the state of the backing bean!
After debugging Mojarra 2.1 I discovered that if you do not included the attribute collectionType it will attempt to clone the backing value class in the process validations phase, which in my case is PersistentSet. Of course adding any value to this will cause a LazyInitializationException.
My question is whether you think this is reasonable behaviour at the process validations phase?
A better algorithm to clone the collection class would be to look at the interface and instantiate a known class from java.util.
Thats exactly the point! It has nothing todo with the session state...
I've ran into this problem and I was able to solve it by adding the following within my component (in my case a selectManyMenu):
<f:attribute name="collectionType" value="java.util.ArrayList" />;
Thanks for the hint to use the collectionType attribute for h:selectMany tags to prevent the LazyInitializationException.
However, instead of flaming about it in an inappropriate forum, how about learning what's new in JSF 2.0, and posting a full example of this problem and how to fix it?
Groundwork:
Mojarra 2.1 is the JSF 2 Reference Implementation (see What is Mojarra)
h:selectManyCheckbox VLD documentation describes how to use the collectionType attribute (new in JSF 2.0)
this problem affects validation of h:selectManyCheckbox, h:selectManyListBox, and h:selectManyMenu tags
Stack Trace of this error:
Feb 04, 2013 1:20:50 PM com.sun.faces.lifecycle.ProcessValidationsPhase execute
WARNING: failed to lazily initialize a collection, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:122)
at org.hibernate.collection.PersistentBag.isEmpty(PersistentBag.java:255)
at javax.faces.component.UIInput.isEmpty(UIInput.java:1257)
at javax.faces.component.UIInput.validateValue(UIInput.java:1144)
at javax.faces.component.UISelectMany.validateValue(UISelectMany.java:579)
Example adding collectionType to fix this error (I am using a custom validator):
<h:selectManyListbox value="${technologyService.entity.associatedLabs}"
collectionType="java.util.ArrayList">
<f:validator validatorId="selectManyListboxValidator" />
<f:attribute name="maxItems" value="5" />
<f:selectItems value="${metadataService.activeLabSelectItems}" />
</h:selectManyListbox>
This question already has answers here:
commandButton/commandLink/ajax action/listener method not invoked or input value not set/updated
(12 answers)
Closed 2 years ago.
my xhtml code:
<h:commandLink action="#{detailController.updateProject}" class="positive" >
<h:graphicImage library="img" name="tick.png" alt=""/>
<h:outputText value="Save" />
</h:commandLink>
This action (updateProject()) is not being called from JSF framework! Even if I delete it in the managedBean there is no exception thrown.
Does anybodyelse has had problems like that? I can't even explain that -.- I mean this action ethod is there!
ADD: Yes it is in a h:form tag! But I have two forms in that view! May that be the problem?
ADD2: I should also mention that if I hit the button it throws me back to the previous view! So my action method is being ignored and instead it opens another view ?!?!
To provide more information, my page is built like that:
panelGroup name=show rendered=!controller.edit
form
buttons
outputtext
/form
/panelGroup
panelGroup name=edit rendered=controller.edit
form
buttons
inputText
/form
/panelGroup
So I have both, edit and show of one entity at one file! But only the buttons in the bottom form show that strange behaviour (see above).
Answering BalusC:
1. I use two forms (they aren't nested!)
2. In the bottom form I had already placed a h:messages
I'm gonna try putting my controller into viewScop for checking 3 and 4
I don't know how to check 5.
Thank you for that..
This can have a lot of possible causes. #romaintaz has mentioned only the most obvious one (the most common beginner's mistake): UICommand components must be placed inside an UIForm component.
There are however more causes:
You have multiple nested forms. This is illegal in HTML. The behaviour is dependent on the webbrowser used, but usually the button won't do anything. You may not nest forms, but you can use them in parallel.
A validation or conversion error has occurred which is not been catched by a h:message. Normally this is logged to stdout, but you can also use h:messages to get them all.
The UICommand component is been placed inside an UIData component (e.g. h:dataTable) whose value is not been preserved the right way during the subsequent request. If JSF cannot find the associated data row, the action won't be invoked. Putting bean in view scope should help a lot.
The component or one of its parents has a rendered or disabled attribute which evaluated false during apply request values phase. JSF won't invoke the action then. Putting bean in view scope should help a lot.
Some PhaseListener, EventListener, Filter or Servlet in the request-response chain has changed the JSF lifecycle to skip the invoke action phase or altered the request parameters so that JSF can't invoke the action.
Just a quick question: is your <h:commandLink> nested inside a <h:form>?
If this is not the case, you must include your command link inside a form element, otherwise it will not work.
Just for code simplification, you can use the value attribute instead of adding a <h:outputText> component:
<h:commandLink action="#{detailController.updateProject}" class="positive" value="Save">
<h:graphicImage library="img" name="tick.png" alt=""/>
</h:commandLink>
Unfortunately, I don't know where the mistae was. I guess it was about wrong my JSF code.
I solved this problem by simplifying my code. From that xhtml page and that one controller I made 3 xhtml-pages and 3 Controller. After refactoring all that my code looks much easier and it works now :-)
Thank you for your helpful suggestions
When using h:commandlink(or commandbutton) inside a rich:dataTable, the action specified is never invoked, neither is the corresponding managed bean instantiated(whether it is at request or session scope)...
instead, the same request is performed.. (page reloads)..
have seen what appeared to be similar issue on forums, but is not actually the problem i am having..
the h:commandlink /button work ok outside of the rich:datatable..
Does anyone have any advice?
here is a code snippet:
<h:commandLink id="commLink" actionListener="#{hBean.test}" action="#{hBean.viewTranslation}">
<h:outputText value="#{trans.translationName}"/>
</h:commandLink>
</rich:column>
The bean is apparently request scoped and the datamodel is not been loaded during bean's construction (at least, during apply request values phase of the subsequent request). You need to preserve the same datamodel for the subsequent request, else JSF cannot locate the row item associated with the clicked link. The most straightforward way is to load the datamodel in the bean's constructor or #PostConstruct method.
A quick fix/test is to put bean in session scope. The datamodel will then be saved in the session scope and be available in the subsequent request. But this has more impact on user experience (e.g. unexpected results when having the same page opened in different browser windows/tabs in the same session). If you're already on JSF 2.0 (which is likely not the case since you're using RichFaces), then the new view scope would have been the solution.
Related questions:
h:commandLink is not been invoked - contains an overview of all possible causes of this behaviour.
If you are using RichFaces 3.0.0 through 3.3.3, use the tag a4j:keepAlive. It will works even with request scope.