In my JSF application using RichFaces, I have a screen with rich:dataTable
that displays my objects, and a column that refers to another page, with the details of the selected record so that it can be used.
In this second page, after completing the requested data, when running submit, the validation returns the message:
:Value is not a valid option.
Look that, unlike the problem cited in this post, the name of the problem field is not being displayed.
During debugging, I noticed that in the selecionarEmitente()
method, the object localidade
is null. If I made the set on the dataTable page and the name of the selected object appears on the secondPage, what is missing?
I already researched other posts about this problem. For example, according to this post, my javabeans involved have the equals()
and hashCode()
methods. Unlike this other post, I'm using custom converters.
Where is my mistake?
I'm using RichFaces 4.5.1.Final, MyFaces 2.2.10, Spring 3.1.1 .
dataTable.xhtml
<h:selectOneMenu id="estado"
immediate="true" validator="#{validadorMB.validarEstado}"
converter="estadoConverter">
<f:selectItem itemLabel="---" />
<f:selectItems value="#{localidadeMB.estados}"
var="est" itemValue="#{est}" itemLabel="#{est.uf}" />
<a4j:ajax event="change" actionListener="#{localidadeMB.filtrarUF}" render="table" />
</h:selectOneMenu>
<a4j:region id="region" immediate="true">
<rich:dataTable id="tabela"
value="#{localidadeMB.getLocalidadesPorUF()}" var="loc"
rowKeyVar="row" rows="20" width="800px" render="scroller">
<rich:column id="col_localidade" sortBy="#{loc.nome}" filterBy="#{loc.nome}">
<h:outputText id="nomeLocalidade" value="#{loc.nome}" />
</rich:column>
...
<rich:column>
<h:commandLink id="declaracaolink" action="#{localidadeMB.carregarLocalidade}">
<h:graphicImage url="/img/declaracao.png" />
<f:setPropertyActionListener value="#{loc}" target="#{localidadeMB.localidade}" />
</h:commandLink>
</rich:column>
</rich:dataTable>
</a4j:region>
secondPage.xhtml
<h:body>
<h:form id="formDeclaracao" focus="estado">
<h:panelGrid columns="2" columnClasses="labelFormulario">
<h:outputLabel value="UF" for="estado" />
<h:selectOneMenu id="estado"
value="#{localidadeMB.localidade.estado}"
label="#{localidadeMB.localidade.estado.uf}"
valueChangeListener="#{localidadeMB.selecionarEstado}"
validator="#{validadorMB.validarEstado}" immediate="true"
converter="estadoConverter"
style="width: 45px;" styleClass="listbox">
<f:selectItems value="#{localidadeMB.estados}"
var="est" itemValue="#{est}" itemLabel="#{est.uf}" />
<a4j:ajax event="change" render="nomeLocalidade" />
</h:selectOneMenu>
<h:outputLabel value="Nome da localidade:" for="nomeLocalidade" />
<h:selectOneMenu id="nomeLocalidade"
value="#{localidadeMB.localidade}"
label="#{localidadeMB.localidade.nome}" immediate="true"
valueChangeListener="#{localidadeMB.selecionarLocalidade}"
validator="#{validadorMB.validarLocalidade}"
converter="localidadeConverter"
style="width: 220px;" styleClass="listbox">
<f:selectItems value="#{localidadeMB.localidades}"
var="loc" itemValue="#{loc}" itemLabel="#{loc.nome}" />
</h:selectOneMenu>
<h:outputLabel value="Interessado:" for="interessado" />
<h:inputText id="interessado" value="" required="true"
requiredMessage="xxxxxxxxx" immediate="true"
styleClass="listbox" style="width: 215px;">
</h:inputText>
<h:outputLabel value="Solicitante:" for="solicitante" />
<h:inputText id="solicitante" value="" required="true"
requiredMessage="xxxxxxxxxxxxx" immediate="true">
</h:inputText>
<h:outputLabel value="Documento apresentado:" for="documento" />
<h:inputText id="documento" value="" required="true"
requiredMessage="xxxxxxxxxxxxx" immediate="true">
</h:inputText>
<h:outputLabel value="Emitente:" for="emitente" />
<h:selectOneMenu id="emitente"
value="#{localidadeMB.emitente}"
label="#{localidadeMB.emitente.descricaoReduzida}"
valueChangeListener="#{localidadeMB.selecionarEmitente}"
validator="#{validadorMB.validarEmitente}"
converter="emitenteConverter">
<f:selectItem itemLabel="---" />
<f:selectItems value="#{localidadeMB.emitentes}" var="em" itemValue="#{em}" itemLabel="#{em.descricaoReduzida}" />
</h:selectOneMenu>
<h:commandButton id="btnGerarDeclaracao" value="Get PDF"
action="#{localidadeMB.getPDF()}" style="width: 84px;" />
</h:panelGrid>
</h:form>
</h:body>
ManagedBean
@ManagedBean
public class LocalidadeMB{
private Emitente emitente;
private Estado estado;
private Localidade localidade;
public String carregarLocalidade() {
estado = localidade.getEstado();
localidade = getLocalidade();
getLocalidades();
carregarLocalidadePorUF(estado);
return "secondPage.xhtml";
}
public void filtrarUF(ActionEvent action) {
try {
String uf = JSFHelper.getRequestParameter("formConsulta"
+ UINamingContainer.getSeparatorChar(JSFHelper
.getFacesContext()) + "estado");
estado = estadoFacade.getEstado(Integer.parseInt(uf));
} catch (Exception e) {
...
}
}
public List<Emitente> getEmitentes() {
try {
return emitenteFacade.getEmitentes();
} catch (Exception e) {
...
}
}
public List<Emitente> getEstados() {
try {
return estadoFacade.getEstados();
} catch (...) {
...
}
}
public List<Localidade> getLocalidades() {
try {
return localidadeFacade.getLocalidades();
} catch (Exception e) {
...
}
}
public List<Localidade> getLocalidadesPorUF() {
try {
String uf = JSFHelper.getRequestParameter("formConsulta"
+ UINamingContainer.getSeparatorChar(JSFHelper
.getFacesContext()) + "estado");
if ((uf != null) && (!uf.equals("---"))) {
estado = estadoFacade.getEstado(Integer.parseInt(uf));
return localidadeFacade.getLocalidadesPorEstado(estado);
} else {
return null;
}
} catch (Exception e) {
...
}
}
public void selecionarEmitente(ValueChangeEvent evento) {
emitente = (Emitente)evento.getNewValue();
}
public void selecionarEstado(ValueChangeEvent evento) {
estado = (Estado)evento.getNewValue();
}
public void selecionarLocalidade(ValueChangeEvent evento) {
localidade = (Localidade)evento.getNewValue();
}
}
Validator
@ManagedBean(name = "validadorMB")
public class ValidadorLocalidadeMB {
public void validarEmitente(FacesContext context, UIComponent componentToValidate, Object value) throws ValidatorException {
if (((Emitente) value).getEmitenteId() == 0) {
FacesMessage msg = new FacesMessage(null, "Selecione o emitente");
throw new ValidatorException(msg);
}
}
public void validarEstado(FacesContext context, UIComponent componentToValidate, Object value) throws ValidatorException {
if (((Estado) value).getEstadoId() == 0) {
FacesMessage msg = new FacesMessage(null, "Selecione uma UF");
throw new ValidatorException(msg);
}
}
public void validarLocalidade(FacesContext context, UIComponent componentToValidate, Object value) throws ValidatorException {
if (((Localidade) value).getLocalidadeId() == 0) {
FacesMessage msg = new FacesMessage(null, "Selecione uma localidade");
throw new ValidatorException(msg);
}
}
}
Converters
@FacesConverter(value = "emitenteConverter")
public class EmitenteConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent ui, String value) throws ConverterException {
ValueExpression vex = context
.getApplication()
.getExpressionFactory()
.createValueExpression(context.getELContext(),
"#{emitenteFacade}", EmitenteFacadeImpl.class);
EmitenteFacadeImpl fac = (EmitenteFacadeImpl) vex.getValue(context
.getELContext());
try {
return fac.getEmitentePorId(Integer.valueOf(value));
} catch (NumberFormatException | DAOException e) {
....
}
}
@Override
public String getAsString(FacesContext context, UIComponent ui, Object value) throws ConverterException {
if (value == null) {
return "";
}
if (value instanceof Emitente) {
return String.valueOf(((Emitente) value).getEmitenteId());
}
}
}
@FacesConverter(value = "estadoConverter")
public class EstadoConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent ui, String value) throws ConverterException {
ValueExpression vex = context
.getApplication()
.getExpressionFactory()
.createValueExpression(context.getELContext(),
"#{estadoFacade}", EstadoFacadeImpl.class);
EstadoFacadeImpl fac = (EstadoFacadeImpl) vex.getValue(context
.getELContext());
try {
return fac.getEstadoPorId(Integer.valueOf(value));
} catch (NumberFormatException | DAOException e) {
....
}
}
@Override
public String getAsString(FacesContext context, UIComponent ui, Object value) throws ConverterException {
if (value == null) {
return "";
}
if (value instanceof Estado) {
return String.valueOf(((Estado) value).getEstadoId());
}
}
}
@FacesConverter(value = "localidadeConverter")
public class LocalidadeConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent ui, String value) throws ConverterException {
ValueExpression vex = context
.getApplication()
.getExpressionFactory()
.createValueExpression(context.getELContext(),
"#{localidadeFacade}", LocalidadeFacadeImpl.class);
LocalidadeFacadeImpl fac = (LocalidadeFacadeImpl) vex.getValue(context.getELContext());
try {
return fac.getLocalidadePorId(Integer.valueOf(value));
} catch (NumberFormatException | DAOException e) {
....
}
}
@Override
public String getAsString(FacesContext context, UIComponent ui, Object value) throws ConverterException {
if (value == null) {
return "";
}
if (value instanceof Localidade) {
return String.valueOf(((Localidade) value).getLocalidadeId());
}
}
}