javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation - jsf

I'm making a project to school in JSF and I have few problems with that.
First of all, the h:commandButton doesn't work properly when I want to redirect myself to another page of the project by pushing it. There is an error displayed:
javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation
index.jsp:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%# taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%# taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
<head>
<title>Firma Komputerowa - Baza Danych</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/table-style.css" />
</head>
<body>
<f:view>
<h:form>
<h:panelGrid columns="3">
<h:commandButton action="#{producentBean.redirect }" value="Dodaj"/>
</h:panelGrid>
<h:panelGrid>
<h:dataTable value="#{producentBean.List}" var="p"
styleClass="order-table"
headerClass="order-table-header"
rowClasses="order-table-odd-row,order-table-even-row" border="1" >
<h:column>
<f:facet name="header">ID producenta</f:facet>
<h:inputText value="#{p.getId}"/>
</h:column>
<h:column>
<f:facet name="header">Nazwa producenta</f:facet>
<h:inputText value="#{p.getNazwa}" />
</h:column>
<h:column>
<f:facet name="header">NIP</f:facet>
<h:inputText value="#{p.getNip}" />
</h:column>
<h:column>
<f:facet name="header">REGON</f:facet>
<h:inputText value="#{p.getRegon}" />
</h:column>
<h:column>
<f:facet name="header">Miasto</f:facet>
<h:inputText value="#{p.getMiasto}" />
</h:column>
<h:column>
<f:facet name="header">Adres</f:facet>
<h:inputText value="#{p.getAdres}" />
</h:column>
<h:column>
<f:facet name="header">Telefon</f:facet>
<h:inputText value="#{p.getTel}" />
</h:column>
<h:column>
<f:facet name="header">E-mail</f:facet>
<h:inputText value="#{p.getEmail}" />
</h:column>
</h:dataTable>
</h:panelGrid>
</h:form>
</f:view>
...
</body>
</html>
ProducentBean.java:
public class ProducentBean extends Polacz implements Serializable {
public String redirect() {
return "dodaj_pr";
}
}
I was trying to do it in many ways, but I can't deal with it.
I also have an another question: is there in JSF a possibility to display a table dynamically from database, for example by choosing a table name selecting an option in ? My database contains three tables with different count of colums each.
I'll be very happy if somebody gives me some advices.
EDIT:
OK, I tried to do this:
private String dodajPrUrl = "dodaj_pr?faces-redirect=true";
public String getDodajPrUrl() {
return this.dodajPrUrl;
}
public void setDodajPrUrl(String newUrl) {
this.dodajPrUrl = newUrl;
}
and in index.jsp:
<h:commandButton action="#{producentBean.redirect }" value="Dodaj" />
It gives me still the same error.
EDIT2:
Stack trace:
SEVERE: javax.faces.FacesException: javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation
javax.faces.FacesException: javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation
at com.sun.faces.context.ExceptionHandlerImpl.handle(ExceptionHandlerImpl.java:142)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:722)
Caused by: javax.faces.component.UpdateModelException: javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation
at javax.faces.component.UIInput.updateModel(UIInput.java:853)
at javax.faces.component.UIInput.processUpdates(UIInput.java:735)
at javax.faces.component.UIData.iterate(UIData.java:2001)
at javax.faces.component.UIData.processUpdates(UIData.java:1253)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
at javax.faces.component.UIForm.processUpdates(UIForm.java:281)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1231)
at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
... 26 more
Caused by: javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation
at com.sun.el.parser.AstValue.setValue(AstValue.java:207)
at com.sun.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:291)
at javax.faces.component.UIInput.updateModel(UIInput.java:818)
... 35 more

Look at the stack trace. Here's the most important part:
Caused by: javax.faces.component.UpdateModelException: javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation
at javax.faces.component.UIInput.updateModel(UIInput.java:853)
at javax.faces.component.UIInput.processUpdates(UIInput.java:735)
at javax.faces.component.UIData.iterate(UIData.java:2001)
at javax.faces.component.UIData.processUpdates(UIData.java:1253)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
at javax.faces.component.UIForm.processUpdates(UIForm.java:281)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1231)
at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
... 26 more
Read from bottom to top. During update model values phase, JSF is traversing the component tree starting from UIViewRoot component (<f:view>). In an UIForm component (<h:form>) there is an UIData component (<h:dataTable>) which has an UIInput component (<h:inputText>) which needs to be processed. The updateModel() basically needs to put the submitted, converted and validated value in the model (the managed bean). However, that operation has failed because the property is not writable (i.e. the setter method cannot be found based on the EL expression syntax).
Well, let's look at the properties of your <h:inputText> components in general.
<h:inputText value="#{p.getId}"/>
...
<h:inputText value="#{p.getNazwa}" />
...
<h:inputText value="#{p.getNip}" />
Wait, that's strange. They start all with "get"! This is definitely not normal. JSF is then looking for methods like setGetId(), setGetNazwa(), etc which just doesn't make sense (and you likely also don't have, given this exception). It's expected that they represent concrete property names like "id", "nazwa", "nip", etc and not full method names.
Thus, so in the model:
private Long id;
private String nazwa;
private String nip;
// Add/generate getters and setters in the following syntax:
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
// ...
And so in the view:
<h:inputText value="#{p.id}"/>
...
<h:inputText value="#{p.nazwa}" />
...
<h:inputText value="#{p.nip}" />
This is however already covered in a bit sane JSF book/tutorial/resource. Are you absolutely positive that you were reading the right one? Your question also shows that you're using JSF 2.0 in combination with the deprecated JSP view technology instead of its successor Facelets. Start at our JSF wiki page.

You have few problems here. First, in your input components you have values like p.getId. In your bean, you probably have methods called getId and setId, but this means that you have property called just id which you can read and write. So change your values to: p.id, p.nazwa, p.nip... You can see that I'm using all lower letters, not Id but id.
Second, you should change your action method to something like this (if you want redirect):
public String redirect() {
return "dodaj_pr?faces-redirect=true";
}
and command button tag to something like this:
<h:commandButton action="#{producentBean.redirect}" value="Dodaj" />

I had the same mistake. The error was that in the value property of the inputext in the EL there were blank spaces between } and " as shown below.
<h:inputText id="txtNroOficio" value="# {bean.nombre} " />
I deleted the blank spaces and it worked.

Don't give the () in your command button. In your bean method return some string and use navigation to move to another page.

Related

JSF javax.el.PropertyNotWritableException and PropertyNotFoundException [duplicate]

I'm making a project to school in JSF and I have few problems with that.
First of all, the h:commandButton doesn't work properly when I want to redirect myself to another page of the project by pushing it. There is an error displayed:
javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation
index.jsp:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%# taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%# taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
<head>
<title>Firma Komputerowa - Baza Danych</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/table-style.css" />
</head>
<body>
<f:view>
<h:form>
<h:panelGrid columns="3">
<h:commandButton action="#{producentBean.redirect }" value="Dodaj"/>
</h:panelGrid>
<h:panelGrid>
<h:dataTable value="#{producentBean.List}" var="p"
styleClass="order-table"
headerClass="order-table-header"
rowClasses="order-table-odd-row,order-table-even-row" border="1" >
<h:column>
<f:facet name="header">ID producenta</f:facet>
<h:inputText value="#{p.getId}"/>
</h:column>
<h:column>
<f:facet name="header">Nazwa producenta</f:facet>
<h:inputText value="#{p.getNazwa}" />
</h:column>
<h:column>
<f:facet name="header">NIP</f:facet>
<h:inputText value="#{p.getNip}" />
</h:column>
<h:column>
<f:facet name="header">REGON</f:facet>
<h:inputText value="#{p.getRegon}" />
</h:column>
<h:column>
<f:facet name="header">Miasto</f:facet>
<h:inputText value="#{p.getMiasto}" />
</h:column>
<h:column>
<f:facet name="header">Adres</f:facet>
<h:inputText value="#{p.getAdres}" />
</h:column>
<h:column>
<f:facet name="header">Telefon</f:facet>
<h:inputText value="#{p.getTel}" />
</h:column>
<h:column>
<f:facet name="header">E-mail</f:facet>
<h:inputText value="#{p.getEmail}" />
</h:column>
</h:dataTable>
</h:panelGrid>
</h:form>
</f:view>
...
</body>
</html>
ProducentBean.java:
public class ProducentBean extends Polacz implements Serializable {
public String redirect() {
return "dodaj_pr";
}
}
I was trying to do it in many ways, but I can't deal with it.
I also have an another question: is there in JSF a possibility to display a table dynamically from database, for example by choosing a table name selecting an option in ? My database contains three tables with different count of colums each.
I'll be very happy if somebody gives me some advices.
EDIT:
OK, I tried to do this:
private String dodajPrUrl = "dodaj_pr?faces-redirect=true";
public String getDodajPrUrl() {
return this.dodajPrUrl;
}
public void setDodajPrUrl(String newUrl) {
this.dodajPrUrl = newUrl;
}
and in index.jsp:
<h:commandButton action="#{producentBean.redirect }" value="Dodaj" />
It gives me still the same error.
EDIT2:
Stack trace:
SEVERE: javax.faces.FacesException: javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation
javax.faces.FacesException: javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation
at com.sun.faces.context.ExceptionHandlerImpl.handle(ExceptionHandlerImpl.java:142)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:722)
Caused by: javax.faces.component.UpdateModelException: javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation
at javax.faces.component.UIInput.updateModel(UIInput.java:853)
at javax.faces.component.UIInput.processUpdates(UIInput.java:735)
at javax.faces.component.UIData.iterate(UIData.java:2001)
at javax.faces.component.UIData.processUpdates(UIData.java:1253)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
at javax.faces.component.UIForm.processUpdates(UIForm.java:281)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1231)
at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
... 26 more
Caused by: javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation
at com.sun.el.parser.AstValue.setValue(AstValue.java:207)
at com.sun.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:291)
at javax.faces.component.UIInput.updateModel(UIInput.java:818)
... 35 more
Look at the stack trace. Here's the most important part:
Caused by: javax.faces.component.UpdateModelException: javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation
at javax.faces.component.UIInput.updateModel(UIInput.java:853)
at javax.faces.component.UIInput.processUpdates(UIInput.java:735)
at javax.faces.component.UIData.iterate(UIData.java:2001)
at javax.faces.component.UIData.processUpdates(UIData.java:1253)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
at javax.faces.component.UIForm.processUpdates(UIForm.java:281)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1231)
at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
... 26 more
Read from bottom to top. During update model values phase, JSF is traversing the component tree starting from UIViewRoot component (<f:view>). In an UIForm component (<h:form>) there is an UIData component (<h:dataTable>) which has an UIInput component (<h:inputText>) which needs to be processed. The updateModel() basically needs to put the submitted, converted and validated value in the model (the managed bean). However, that operation has failed because the property is not writable (i.e. the setter method cannot be found based on the EL expression syntax).
Well, let's look at the properties of your <h:inputText> components in general.
<h:inputText value="#{p.getId}"/>
...
<h:inputText value="#{p.getNazwa}" />
...
<h:inputText value="#{p.getNip}" />
Wait, that's strange. They start all with "get"! This is definitely not normal. JSF is then looking for methods like setGetId(), setGetNazwa(), etc which just doesn't make sense (and you likely also don't have, given this exception). It's expected that they represent concrete property names like "id", "nazwa", "nip", etc and not full method names.
Thus, so in the model:
private Long id;
private String nazwa;
private String nip;
// Add/generate getters and setters in the following syntax:
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
// ...
And so in the view:
<h:inputText value="#{p.id}"/>
...
<h:inputText value="#{p.nazwa}" />
...
<h:inputText value="#{p.nip}" />
This is however already covered in a bit sane JSF book/tutorial/resource. Are you absolutely positive that you were reading the right one? Your question also shows that you're using JSF 2.0 in combination with the deprecated JSP view technology instead of its successor Facelets. Start at our JSF wiki page.
You have few problems here. First, in your input components you have values like p.getId. In your bean, you probably have methods called getId and setId, but this means that you have property called just id which you can read and write. So change your values to: p.id, p.nazwa, p.nip... You can see that I'm using all lower letters, not Id but id.
Second, you should change your action method to something like this (if you want redirect):
public String redirect() {
return "dodaj_pr?faces-redirect=true";
}
and command button tag to something like this:
<h:commandButton action="#{producentBean.redirect}" value="Dodaj" />
I had the same mistake. The error was that in the value property of the inputext in the EL there were blank spaces between } and " as shown below.
<h:inputText id="txtNroOficio" value="# {bean.nombre} " />
I deleted the blank spaces and it worked.
Don't give the () in your command button. In your bean method return some string and use navigation to move to another page.

Error Omnifaces o:validateOrder with Rich Faces Calendar component

I have a problem when try to validate the rich:calendar component with o:validateOrder.
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:tablas="http://java.sun.com/jsf/composite/tablas"
xmlns:o="http://omnifaces.org/ui"
xmlns:of="http://omnifaces.org/functions"
xmlns:templates="http://java.sun.com/jsf/composite/templates"
>
<body>
<f:metadata>
<f:event type="preRenderView" listener="#{baseController.iniciarConversacion()}" />
</f:metadata>
<ui:composition template="/templates/TemplateABM.xhtml">
<ui:define name="title">
#{msgs['facturacion.abm.generacion.factura.individual.pagina.titulo']}
</ui:define>
<ui:define name="top">
<h1>#{msgs['facturacion.abm.generacion.factura.individual.titulo']}</h1>
</ui:define>
<ui:define name="content">
<h:form id="formFacturaIndividual">
<h:panelGroup id="panelFechas">
<h:inputHidden id="fechaInicioFactura" value="#{facturaController.fechaInicioFactura}">
<f:convertDateTime type="date" pattern="dd/MM/yy"/>
</h:inputHidden>
<h:inputHidden id="fechaFinFactura" value="#{facturaController.fechaFinFactura}">
<f:convertDateTime type="date" pattern="dd/MM/yy"/>
</h:inputHidden>
<h:inputHidden id="fechaEmisionComprobanteUltima" value="#{comprobanteController.fechaEmisionComprobanteUltima}">
<f:convertDateTime type="date" pattern="dd/MM/yy"/>
</h:inputHidden>
</h:panelGroup>
<o:validateOrder id="validacionFechaFacturaMenorAFechaInicioFactura" type="gte" components="fechaFactura fechaInicioFactura"
message="#{msgs['comun.abm.fecha.factura.menor.limite.dia']}" showMessageFor="fechaFactura" />
<o:validateOrder id="validacionFechaFacturaMayorAFechaFinFactura" type="lte" components="fechaFactura fechaFinFactura"
message="#{msgs['comun.abm.fecha.factura.menor.limite.dia']}" showMessageFor="fechaFactura" />
<o:validateOrder id="validacionFechaFacturaMayorAFechaEmisionUltimoComprobante" type="gte" components="fechaFactura fechaEmisionComprobanteUltima"
message="#{of:format1(msgs['comun.abm.fecha.factura.menor.ultimo.comprobante'], comprobanteController.fechaEmisionComprobanteUltima)}" showMessageFor="fechaFactura" />
<o:massAttribute name="disabled" value="#{tipoComprobanteController.entidad == null}">
<rich:panel id="panelDatosFactura" header="#{msgs['facturacion.abm.generacion.padron.panel.datos.factura']}">
<h:panelGrid id="DatosFactura" columns="3">
<h:outputLabel value="#{msgs['facturacion.abm.generacion.padron.fecha.factura']}" for="fechaFactura"/>
<rich:calendar
id="fechaFactura"
datePattern="dd/MM/yyyy"
showWeeksBar="false"
enableManualInput="true"
value="#{generacionFacturacionIndividualController.facturaBean.fechaFactura}"
required="true"
requiredMessage="La Fecha de la Factura es Obligatoria" >
<a4j:ajax event="change" execute="#form" />
</rich:calendar>
<h:panelGroup>
<rich:message for="fechaFactura"/>
</h:panelGroup>
</h:panelGrid>
</rich:panel>
</o:massAttribute>
</h:form>
</ui:define>
</ui:composition>
</body>
</html>
Exception:
java.lang.IllegalArgumentException: All values must implement java.lang.Comparable.
at org.omnifaces.component.validator.ValidateOrder.validateValues(ValidateOrder.java:142)
at org.omnifaces.component.validator.ValidateMultipleFields.validateComponents(ValidateMultipleFields.java:213)
at org.omnifaces.component.validator.ValidatorFamily.processValidators(ValidatorFamily.java:63)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1216)
at javax.faces.component.UIForm.processValidators(UIForm.java:253)
at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:536)
at org.richfaces.context.MetaComponentProcessingVisitCallback.visit(MetaComponentProcessingVisitCallback.java:73)
at org.richfaces.context.BaseExtendedVisitContext.invokeVisitCallback(BaseExtendedVisitContext.java:103)
at org.richfaces.context.ExtendedExecuteVisitContext.invokeVisitCallback(ExtendedExecuteVisitContext.java:55)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1652)
at javax.faces.component.UIForm.visitTree(UIForm.java:371)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1663)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1663)
at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:383)
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:257)
at org.richfaces.context.ExtendedPartialViewContext.processPartial(ExtendedPartialViewContext.java:263)
at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1162)
at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at ar.com.filter.HibernateSessionRequestFilter.doFilter(HibernateSessionRequestFilter.java:35)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassCastException: java.util.Date cannot be cast to java.lang.String
at java.lang.String.compareTo(String.java:108)
at java.util.Collections$ReverseComparator.compare(Collections.java:3578)
at java.util.Collections$ReverseComparator.compare(Collections.java:3569)
at java.util.TimSort.countRunAndMakeAscending(TimSort.java:324)
at java.util.TimSort.sort(TimSort.java:189)
at java.util.TimSort.sort(TimSort.java:173)
at java.util.Arrays.sort(Arrays.java:659)
at java.util.Collections.sort(Collections.java:217)
at org.omnifaces.component.validator.ValidateOrder$Type$4.invoke(ValidateOrder.java:99)
at org.omnifaces.component.validator.ValidateOrder$Type$4.invoke(ValidateOrder.java:95)
at org.omnifaces.component.validator.ValidateOrder$Type.validateOrder(ValidateOrder.java:111)
at org.omnifaces.component.validator.ValidateOrder.validateValues(ValidateOrder.java:139)
... 44 more
I debuged the code and the problem is that the rich:calendar component send String instead Date type, this doesn't happen me in other pages i dont know is omnifaces problem or richfaces. Any ideas?
The <o:validateXxx> components are sensitive to their location relative to the target input components. This is very useful to prioritize validation depending on component's own converter and validators.
When placed before the target input components, then they will validate the raw unsubmitted values, and they will run before any of component's own validators.
When placed after the target input components, then they will validate the converted values (if any converter is involved), and they will run after any of component's own validators.
In your particular case, you placed the <o:validateOrder> between those components. This is not the recommended approach. You will end up getting a List filled with Date instances from components above the validator and String instances from components below the validator.
See also the ValidateMultipleFields javadoc (emphasis mine):
This validator can be placed anywhere in the form, but keep in mind that the components will be validated in the order as they appear in the form. So if this validator is been placed before all of the components, then it will be executed before any of the component's own validators. If this validator fails, then the component's own validators will not be fired. If this validator is been placed after all of the components, then it will be executed after any of the component's own validators. If any of them fails, then this validator will not be exeucted. It is not recommended to put this validator somewhere in between the referenced components as the resulting behaviour may be confusing. Put this validator either before or after all of the components, depending on how you would like to prioritize the validation.

Composite Components with Composite Children mixing up values when used with ui:repeat

I am trying to make two composite componenets play well together by nesting one as a child.
The setup consists of a lightbox and a input both with an attribute called "Value". This works fine, until i introduce a dynamic
number of inputs, and therefore have to use a ui:repeat.
bugTest.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:pw="http://java.sun.com/jsf/composite/components">
<h:head></h:head>
<h:body>
<pw:lightBox value="Header">
<h:form>
<ui:repeat var="input" value="#{BugTestBean.inputs}">
<pw:bugTestInput value="#{input}" />
</ui:repeat>
</h:form>
</pw:lightBox>
</h:body>
</html>
The ui:repeat seems to get the value attribute of the two components mixed up, and the following exception occurs.
Caused by: javax.el.PropertyNotFoundException: /resources/components/bugTestInput.xhtml #15,62 value="#{cc.attrs.value.text}": The class 'java.lang.String' does not have the property 'text'.
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:111)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
at javax.faces.component.UIOutput.getValue(UIOutput.java:170)
at javax.faces.component.UIInput.getValue(UIInput.java:284)
at com.sun.faces.facelets.component.UIRepeat$SavedState.populate(UIRepeat.java:879)
at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:396)
at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:402)
at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:402)
at com.sun.faces.facelets.component.UIRepeat.saveChildState(UIRepeat.java:356)
at com.sun.faces.facelets.component.UIRepeat.setIndex(UIRepeat.java:470)
at com.sun.faces.facelets.component.UIRepeat.process(UIRepeat.java:586)
at com.sun.faces.facelets.component.UIRepeat.encodeChildren(UIRepeat.java:1042)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1819)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:847)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:304)
at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:105)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:847)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:304)
at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:105)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:847)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1819)
at com.sun.faces.renderkit.html_basic.CompositeRenderer.encodeChildren(CompositeRenderer.java:78)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:847)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1819)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1822)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1822)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:447)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
at com.ocpsoft.pretty.faces.application.PrettyViewHandler.renderView(PrettyViewHandler.java:159)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
... 33 more
It seems like the value of the lightbox is being passed to the inputs.
have boiled the example down to a minimum to produce the error.
I have tried on Mojarra 2.1.26, and 2.2.4.
BugTestBean.java
#ManagedBean(name="BugTestBean")
#ViewScoped
public class BugTestBean {
private List<BugTestInput> inputs;
public BugTestBean() {
inputs = new ArrayList<BugTestInput>();
inputs.add(new BugTestInput("Test1"));
inputs.add(new BugTestInput("Test2"));
inputs.add(new BugTestInput("Test3"));
inputs.add(new BugTestInput("Test4"));
}
public List<BugTestInput> getInputs() {
return inputs;
}
}
bugTestInput.xhtml
<cc:interface>
<cc:attribute name="value" />
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<h:inputText id="input" value="#{cc.attrs.value.text}" />
</div>
</cc:implementation>
BugTestInput.java
public class BugTestInput {
private String text;
public BugTestInput(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
lightbox.xhtml
<cc:interface>
<cc:attribute name="value" />
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<h:outputText value="#{cc.attrs.value}" />
<h:panelGroup>
<cc:insertChildren />
</h:panelGroup>
</div>
</cc:implementation>
Current Solutions
Renaming the attribute value to something else on the lightbox fixes this problem.
Leaving the attribute value empty on the lightbox also works.
Not using the ui:repeat will also fix the problem, but this isn't solid.
Currently i am using 2 attributes on the lightbox and leaving the value empty when needed
<h:outputText value="#{cc.attrs.value}#{cc.attrs.title}" />
Follow up
Regardless of what the attribute name is, if they are the same on both components it will fail.
Is this a bug in JSF, i have searched the bug trackers and most new patch notes without result.
Have you tried using <c:forEach> tag under JSTL, instead of <ui:repeat>? I have always faces issues with the <ui:repeat> tag.
<c:forEach> should work if you do not re-render the component using ajax calls.

Issue in a JSF 2.0 Application

I am using JSF 2.0 in a simple application. I have three beans 1st which is login is in request scope while other 2 in view scope. I have configured in faces-config.xml.
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<navigation-rule>
<from-view-id>*</from-view-id>
<navigation-case>
<from-outcome>loginSuccess</from-outcome>
<to-view-id>/pages/ReportSubmit.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>reportStatus</from-outcome>
<to-view-id>/pages/ReportStatus.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>logout</from-outcome>
<to-view-id>/pages/logout.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<managed-bean>
<managed-bean-name>UserBean</managed-bean-name>
<managed-bean-class>com.cognizant.reportgen.LoginBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>ReportBean</managed-bean-name>
<managed-bean-class>com.cognizant.reportgen.ReportGeneratorBean</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>ReportStatus</managed-bean-name>
<managed-bean-class>com.cognizant.reportgen.ReportStatusBean</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
</managed-bean>
</faces-config>
I have a menu.jsp which has below code
menu item1 <h:commandLink action="loginSuccess" value="Generate Reports"></h:commandLink>
menu item 2<h:commandLink action="reportStatus" value="Report Status"></h:commandLink>
In 2 beans, I have methods whose return type is void.
On Login request, I am creating session and setting user detail in session attribute.
Now The problem which I am facing is that
I login with user1, select menu item 1, so corresponding data is displayed.
I login with user2 in next browser window, select menu item 1, so corresponding data is displayed.
I go back to browser window1 (user1), select menu item 1 again, but now in header it displays the user2 name., Also it displays data corresponding to user2.
Please help me with this issue.
//ReportStatusBean.java
public class ReportStatusBean {
private List<ReportAttrDO> reportList;
private HtmlDataTable reportStatusTable;
// getters and setter for above included....
public void checkReportStatus(ActionEvent event) {
ReportGenService reportGenObj = new ReportGenServiceImpl();
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
UserDetail user = (UserDetail)session.getAttribute("user");
List<ReportAttrDO> reportList = reportGenObj.getReportStatusList(user.getUserId());
setReportList(reportList);
if(reportList.isEmpty())
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "No Records to display.", null));
}
public void viewReport(ActionEvent event) {
ReportAttrDO reportAttrDO = (ReportAttrDO)getReportStatusTable().getRowData();
System.out.println(reportAttrDO.getRequestHeaderId());
}
}
// ReportStatus.jsp
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%# taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<f:view>
<html>
<head>
....some script functions..
</head>
<body onload="noBack();" onpageshow="if (event.persisted) noBack();" onunload="">
<center>
<div class="wrapper">
<%#include file="../include/pageheader.jsp"%>
<%#include file="../include/menu.jsp"%>
<h:form id="form2">
<table border="0">
<tr>
<td colspan="2"><h:messages style="color:red;margin:8px;" /></td>
</tr>
<tr>
<td colspan="2"><h:commandButton value="Check Status" actionListener="#{ReportStatus.checkReportStatus}" /></td>
</tr>
</table>
<c:if test="${not empty ReportStatus.reportList}" >
<div style="height:200px;width:600px;overflow:auto;">
<h:dataTable id="table" border="1"
var="row" value="#{ReportStatus.reportList}" cellpadding="5" cellspacing="5"
binding="#{ReportStatus.reportStatusTable}">
<h:column>
<f:facet name="header">
<f:verbatim>
<h:outputText value="Application Name" />
</f:verbatim>
</f:facet>
<h:outputText id="applName" value="#{row.applicationName}" ></h:outputText>
</h:column>
<h:column>
<f:facet name="header">
<f:verbatim>
<h:outputText value="Report Name" />
</f:verbatim>
</f:facet>
<h:outputText id="reportReqName" value="#{row.reportRequestName}"></h:outputText>
</h:column>
<h:column>
<f:facet name="header">
<f:verbatim>
<h:outputText value="Generated Report" />
</f:verbatim>
</f:facet>
<h:commandLink id="viewReport" value="View" rendered="#{row.status == 'Completed'}" actionListener="#{ReportStatus.viewReport}"></h:commandLink>
</h:column>
</h:dataTable>
</div>
</c:if>
</h:form>
</div>
</center>
</body>
</html>
</f:view>
HTTP session is shared among browser's tabs, so what you're experiencing is an expected behaviour. When you did login in a next tab you most probably replaced the existing session attribute.
You can as well try it in different browsers, but not different tabs of the same browser, to see it work as you expect it to work. In the end, session is a per user construct and should be viewed as such. You must define the proper scopes for your beans for the application to run in accordance with your expectations and for good user experience.
Unrelated to your concrete problem, using command links that use POST requests for plain page-to-page navigation is considered to be a bad practice: you should use <h:link> instead. For details see the third reference below.
Also, using faces-config.xml to solely configure navigation rules and declare managed beans in a JSF 2.0 application is somewhat old-school, in my opinion. The last but not the least, JSP is a deprecated view technology nowadays, that was superseded by facelets, so developing new application using JSP as a view technology should be carefully rethought.
See also:
How to choose the right bean scope?;
Communication in JSF 2.0, section on bean scopes;
When should I use h:outputLink instead of h:commandLink?.
You need to render your menu conditionnaly of your session user and not your login result, for example :
<h:form>
<h:panelGroup rendered="#{not userbean.isLogged}">
<h:inputText value="#{userBean.username}" />
<h:inputText value="#{userBean.password}" />
<h:commandButton actionListener="#{userBean.login}" />
</h:panelGroup>
<h:panelGroup rendered="#{userBean.isLogged}">
<h:commandLink rendered="#{userBean.user eq "user1"}" action="loginSuccess" value="Generate Reports"></h:commandLink>
<h:commandLink rendered="#{userBean.user eq "user2"}" action="reportStatus" value="Report Status"></h:commandLink>
</h:panelGroup>
</h:form>
Of course it will require some function inside userBean to get the username for example.
Also you mean that you have configured your bean using ViewScoped, they are all RequestScoped in the code provided.
I suggest you to use .xhtml file name extensions, which is the standard in JavaServer Faces views.

Dynamically adding fields to JSF form

I have the following situation that I would like to handle in JSF. My form consists of family information (name/address/phone) and then children information. Since a family can have more then one child, I need to be able to allow the person to click "add more children" and another child "section" will appear.
Here is a simple test case I've thrown together.
Backing Bean. A family has a list of children.
#ViewScoped
#ManagedBean
public class TestBackingBean implements Serializable {
private Family f = new Family();
private Child childToRemove;
public TestBackingBean() {
f.addChild(new Child());
}
public Family getFamily() {
return f;
}
public void setChildToRemove(Child childToRemove) {
this.childToRemove = childToRemove;
}
public TimeZone getTimezone() {
return TimeZone.getDefault();
}
public List<Child> getChildren() {
return f.getChildrenAsList();
}
public Child getChildToRemove() {
return childToRemove;
}
public void addChild() {
f.addChild(new Child());
}
public void removeChild() {
f.removeChild(childToRemove);
}
}
Here is the JSF page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title><ui:insert name="title" />
</title>
<link rel="stylesheet" type="text/css" href="/hcbb/css/main.css" />
</h:head>
<h:body>
<h:form>
<h:panelGroup id="parentSection">
<h:outputLabel value="Parent Name" for="parent_firstName" />
<h:inputText id="parent_firstName" requiredMessage="Required"
immediate="true" label="Parent First Name"
value="#{testBackingBean.family.firstName}">
<f:validateRequired />
</h:inputText>
<rich:message id="parent_firstNameMessage" for="parent_firstName" />
</h:panelGroup>
<h:panelGroup id="childrenSection">
<h:dataTable value="#{testBackingBean.children}" var="child">
<h:column>
<h:panelGrid id="childPanel" columns="3"
style="border:1px solid brown; padding: 5px; margin-bottom:5px; width: 600px;">
<h:outputText id="childTitle" value="Child"
style="font-weight: bold;" />
<h:outputText id="spacer" />
<a4j:commandButton id="removeBtn"
action="#{testBackingBean.removeChild}" immediate="true"
value="Remove Child" render="childrenSection"
style="float:right;" title="Remove">
<f:setPropertyActionListener
target="#{testBackingBean.childToRemove}" value="#{child}" />
</a4j:commandButton>
<h:outputLabel id="child_firstNameLbl" value="First Name" />
<h:inputText id="child_firstName" requiredMessage="Required"
immediate="true" label="Child First Name"
value="#{child.firstName}">
<f:validateRequired />
</h:inputText>
<rich:message id="child_firstNameMessage" for="child_firstName" />
<h:outputLabel id="child_lastNameLbl" value="Last Name" />
<h:inputText id="child_lastName" requiredMessage="Required"
immediate="true" label="Child Last Name"
value="#{child.lastName}">
<f:validateRequired />
</h:inputText>
<rich:message id="child_lastNameMessage" for="child_lastName" />
<h:outputLabel id="child_dobLbl" value="Birth Date" />
<h:inputText id="child_dob" label="Child Birth Date"
immediate="true" requiredMessage="Required"
value="#{child.dateOfBirth}">
<f:convertDateTime id="dobConverter" pattern="MM/dd/yyyy"
timeZone="#{testBackingBean.timezone}" />
<f:validateRequired />
</h:inputText>
<rich:message id="child_dobNameMessage" for="child_dob" />
</h:panelGrid>
</h:column>
</h:dataTable>
<a4j:commandLink id="addChildBtn" immediate="true"
render="childrenSection" action="#{testBackingBean.addChild}"
value="Add Another Child">
</a4j:commandLink>
</h:panelGroup>
</h:form>
</h:body>
</html>
The issue is the saving of the values when adding/removing child sections. If you enter parent name and then child name and date of birth and then click add the fields for the child you just added will disappear? I would have thought that immediate=true on the button and the fields will get them through.
The problem is add a parent first name, enter child info and click the add another child button and the child information you just entered will be erased.
Any suggestions on how I might be able to make this all work. Seems like a fairly simple and somewhat standard use case.
Thanks!
It looks fine at the first glance. The problem symptoms boils down that the f.getChildrenAsList() doesn't return a list with the new child while JSF is about to apply request values. Perhaps that method is re-fetching the list from DB again upon submit? Add a breakpoint to investigate its retun value. Or perhaps the view scope failed and caused the bean to be reconstructed? Add a breakpoint to the bean's constructor. It should not be reconstructed when you're submitting the form against the same view.
As to using the immediate attribute, all your usage of them is entirely superfluous. Just remove them. To understand its use better, get yourself through the Debug JSF lifecycle article (true, it's JSF 1.2 targeted, but the principles are the same for JSF2) and then read particularly this summary:
Okay, when should I use the immediate attribute?
If it isn't entirely clear yet, here's a summary, complete with real world use examples when they may be beneficial:
If set in UIInput(s) only, the process validations phase will be taken place in apply request values phase instead. Use this to prioritize validation for the UIInput component(s) in question. When validation/conversion fails for any of them, the non-immediate components won't be validated/converted.
If set in UICommand only, the apply request values phase until with update model values phases will be skipped for any of the UIInput component(s). Use this to skip the entire processing of the form. E.g. "Cancel" or "Back" button.
If set in both UIInput and UICommand components, the apply request values phase until with update model values phases will be skipped for any of the UIInput component(s) which does not have this attribute set. Use this to skip the processing of the entire form expect for certain fields (with immediate). E.g. "Password forgotten" button in a login form with a required but non-immediate password field.

Resources