SelectOneMenu + PrimeFaces - Valor não é válido

406 views
Skip to first unread message

Marcos Rodrigues

unread,
Aug 25, 2016, 4:06:23 PM8/25/16
to javasf: JavaServer Faces Group, Marcos Rodrigues
Boa tarde gente.

Estou com um projeto em JSF, CDI e PrimeFaces, Eu preciso atualizar os valores de um combobox (p:selectOneMenu) a partir de um botao (p:selectOneButton). A principio, esse selectOneMenu está vazio, e depois de eu selecionar o selectOneMenu, vou buscar os dados do banco de dados e filtrar somente os dados relacionados com o selectOneMenu (que é um enum).

Eu consegui fazer a atualização dinâmica do selectOneMenu, mas toda vez que eu tento salvar algum registro, a validação me retorna "Erro de validação: o valor não é válido".

Fiz a classe Converter, sobrescrevi os métodos Equals e HashCode, mas ainda não consegui resolver.
Segue códigos:

NovaLinhaPesquisa.xhtml
<!DOCTYPE html>
<ui:composition template="/WEB-INF/template/LayoutAluno.xhtml"
 
xmlns="http://www.w3.org/1999/xhtml"
 
xmlns:f="http://xmlns.jcp.org/jsf/core"
 
xmlns:h="http://xmlns.jcp.org/jsf/html"
 
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
 
xmlns:p="http://primefaces.org/ui"
 
xmlns:o="http://omnifaces.org/ui">
 
 
<f:metadata>
 
<o:viewParam name="id" value="#{cadastroLinhaPesquisaBean.linhaPesquisa}"/>
 
<f:viewAction action="#{cadastroLinhaPesquisaBean.processar}"></f:viewAction>
 
</f:metadata>
 
 
<ui:define name="titulo">Nova Linha de Pesquisa - Fichas Catalográficas</ui:define>
 
 
<ui:define name="pre-texto">
 Esta página tem como objetivo cadastrar novas linhas de pesquisa que não se encontram no sistema.
<br />
 Certifique-se de que a linha de pesquisa realmente não está cadastrado para o programa de pós graduação escolhida. Caso contrário, o registro será duplicado.
<br />
 
</ui:define>
 
 
<ui:define name="formulario">
 
<h1>Cadastro de nova linha de pesquisa para programas de pós graduação</h1>
 
 
<h:form id="frm" role="form" class="form-horizontal">
 
<h:messages showDetail="false" showSummary="true" autoUpdate="true"
 
errorStyle="color: red;" infoStyle="color: green;"
 
warnStyle="color: orange;" fatalStyle="color: grey;"/>
 
 
<div class="wizard-header">
             
           
</div>
           
<div class="wizard-content">
               
<div class="form-group">
               
<h:outputLabel value="Modalidade do curso:* " for="modalidade" styleClass="col-sm-3 control-label" />
               
<!-- Este é o selectOneButton -->
               
<p:selectOneButton id="modalidade"
                   
value="#{cadastroLinhaPesquisaBean.linhaPesquisa.programaPosGraduacao.modalidadeCurso}">
                   
<p:ajax event="change" update="programasPosGraduacao" process="@this"
 
listener="#{cadastroLinhaPesquisaBean.modalidadeCursoAlterado}" />
                   
                   
<f:selectItems
                   
value="#{cadastroLinhaPesquisaBean.modalidadeCurso}" var="modalidadeCurso"
                   
itemLabel="#{modalidadeCurso.descricao}" itemValue="#{modalidadeCurso}" />
                   
</p:selectOneButton>
               
</div>
               
               
<div class="form-group">
               
<h:outputLabel value="Programa de pós graduação:* " for="programasPosGraduacao" styleClass="col-sm-3 control-label" />
               
<div class= "col-sm-9">
               
<!-- Este é o selectOneMenu, que vai buscar todas as pós graduação relacionadas à modalidade escolhida -->
               
<h:selectOneMenu id="programasPosGraduacao" immediate="true"
               
value="#{cadastroLinhaPesquisaBean.linhaPesquisa.programaPosGraduacao}" class="form-control">
               
<f:selectItem noSelectionOption="true" itemLabel="Selecione a modalidade do curso" itemValue="" />
               
<f:selectItems value="#{cadastroLinhaPesquisaBean.todosProgramas}" var="programas"
               
itemLabel="#{programas.programa}" itemValue="#{programas.id}"/>
               
</h:selectOneMenu>
               
</div>
               
</div>
               
               
               
<div class="form-group">
               
<h:outputLabel value="Nova linha de pesquisa:* " for="linhaDePesquisa" styleClass="col-sm-3 control-label" />
               
<div class="col-sm-9">
               
<h:inputText value="#{cadastroLinhaPesquisaBean.linhaPesquisa.linhaPesquisa}"
               
id="linhaDePesquisa" styleClass="form-control small-lg" />
               
</div>
           
</div>
               
           
<div class="form-group">
             
<div class="col-sm-3" />
             
<div class="col-sm-9">
             
<p:commandButton action="#{cadastroLinhaPesquisaBean.salvar}" update="@form"
             
value="Cadastrar" styleClass="wizard-finish btn btn-primary" />
                 
</div>
             
</div>
           
</div>
 
</h:form>
 
</ui:define>
</ui:composition>

CadastroLinhaPesquisaBean.java
package com.ufop.fichas.bean;

import java.io.Serializable;

@Named
@ViewScoped
public class CadastroLinhaPesquisaBean implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
private CadastroLinhaDePesquisa cadastro;
@Inject
private ProgramaPosGraduacaoRepository programaRepository;
private List<ProgramaPosGraduacao> todosProgramas;
private LinhaDePesquisa linhaPesquisa = new LinhaDePesquisa();
public void processar() {
if (this.linhaPesquisa == null) {
this.linhaPesquisa = new LinhaDePesquisa();
this.linhaPesquisa.setProgramaPosGraduacao(new ProgramaPosGraduacao());
}
}
public void teste(AjaxBehaviorEvent event) {
System.out.println("teste");
}
public void salvar() {
FacesContext context = FacesContext.getCurrentInstance();

try {
this.cadastro.salvar(linhaPesquisa);
this.linhaPesquisa = new LinhaDePesquisa();
this.linhaPesquisa.setProgramaPosGraduacao(new ProgramaPosGraduacao());
context.addMessage(null, new FacesMessage("Programa de Pós Graduação cadastrado com sucesso !"));
} catch (NegocioException e) {
FacesMessage message = new FacesMessage(e.getMessage());
message.setSeverity(FacesMessage.SEVERITY_ERROR);
context.addMessage(null, message);
}
}
public List<ProgramaPosGraduacao> getTodosProgramas() {
return this.todosProgramas;
}
public LinhaDePesquisa getLinhaPesquisa() {
return linhaPesquisa;
}

public void setlinhaPesquisa(LinhaDePesquisa linhaPesquisa) {
this.linhaPesquisa = linhaPesquisa;
}
public ProgramaPosGraduacao getProgramaPosGraduacao() {
return this.linhaPesquisa.getProgramaPosGraduacao();
}
public void setProgramaPosGraduacao(ProgramaPosGraduacao programaPosGraduacao) {
this.linhaPesquisa.setProgramaPosGraduacao(programaPosGraduacao);
}
public ModalidadeCurso[] getModalidadeCurso() {
return ModalidadeCurso.values();
}
public void modalidadeCursoAlterado(AjaxBehaviorEvent event) {
this.todosProgramas = programaRepository.byModalidade(this.getLinhaPesquisa().getProgramaPosGraduacao().getModalidadeCurso());
}
}


ProgramaPosGraduacao.java (com o equals e o hashcode)
package com.ufop.fichas.model;

import java.io.Serializable;

@Entity
@Table(name = "programaPosGraduacao")
public class ProgramaPosGraduacao implements Serializable {

private static final long serialVersionUID = 1L;
private Long id;
private String programa;
private ModalidadeCurso modalidade;
/*
            Gets e Sets
        */
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
if (obj instanceof ProgramaPosGraduacao) {
ProgramaPosGraduacao other = (ProgramaPosGraduacao) obj;
return id == other.id
&& programa == other.programa
&& modalidade == other.modalidade;
}
return false;
}
}


ProgramaPosGraduacaoConverter.java
package com.ufop.fichas.converter;

import com.ufop.fichas.model.ProgramaPosGraduacao;
import com.ufop.fichas.repository.ProgramaPosGraduacaoRepository;

@FacesConverter(forClass = ProgramaPosGraduacao.class)
public class ProgramaPosGraduacaoConverter implements Converter {
@Inject
private ProgramaPosGraduacaoRepository programaPosGraduacao;
@Override
public Object getAsObject(FacesContext context,
UIComponent component, String value) {
if(value != null && !"".equals(value)) {
return this.programaPosGraduacao.byId(new Long(value));
}
return null;
}
@Override
public String getAsString(FacesContext context,
UIComponent component, Object value) {
if (value != null) {
ProgramaPosGraduacao programa = ((ProgramaPosGraduacao) value);
return programa.getId() == null ? null : programa.getId().toString();
}
return null;
}
}

No método equals, quando eu depurei, reparei que a variável "obj" do tipo Object sempre me retorna um tipo "Long", e a validação nunca passa dessa linha:
if (getClass() != obj.getClass()) return false;
if (obj instanceof ProgramaPosGraduacao) {
//code
}

Mas não sei o motivo disso. Li que poderia ser em relação ao escopo do meu projeto, que está usando o ViewScopped no CadastroLinhaPesquisaBean.java, mas quando eu mudo para RequestScopped, ele não consegue renderizar os valores do selectOneButton.

Segue em anexo o erro de validação que está acontecendo !

Alguém já passou por isso e pode me ajudar ?! :)

Abraços
Erro Validação.png

Davi Mustafa

unread,
Aug 25, 2016, 4:36:11 PM8/25/16
to javasf: JavaServer Faces Group
Na tua pagina tu n ta chamando o converter em canto nenhum neh. Ja tentou isso? Não lembro se por o "forClass" faz com que tu n precise usar la na pagina. Mas tenta ai

--
Você recebeu essa mensagem porque está inscrito no grupo "javasf: JavaServer Faces Group" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para javasf+unsubscribe@googlegroups.com.
Acesse esse grupo em https://groups.google.com/group/javasf.
Para ver essa discussão na Web, acesse https://groups.google.com/d/msgid/javasf/de15b920-a85a-407f-9829-cd38a4a3cbd9%40googlegroups.com.
Para mais opções, acesse https://groups.google.com/d/optout.



--
Davi Mustafa

Davi Mustafa

unread,
Aug 25, 2016, 4:42:22 PM8/25/16
to javasf: JavaServer Faces Group

Rafael Ramon

unread,
Aug 25, 2016, 5:55:21 PM8/25/16
to jav...@googlegroups.com

Robson

unread,
Aug 29, 2016, 8:22:10 AM8/29/16
to javasf: JavaServer Faces Group, marcos.ro...@gmail.com
Olá Bom dia.

Prezado tive uma verdadeira Maratona com este problema que.... muitas vezes tem a ver com conversor, tem a ver com sobrescrever alguns métodos em suas classes no modelo, mais no meu caso tudo isto estava certo porém ainda no modelo tinha algo errado e era no relacionamento que eu tinha colocado, o pessoal aqui foi muito proativo e eu consegui resolver.

Jivago Silva

unread,
Aug 29, 2016, 10:57:32 AM8/29/16
to javasf: JavaServer Faces Group, marcos.ro...@gmail.com
Esse valor é long? 
value="#{cadastroLinhaPesquisaBean.linhaPesquisa.programaPosGraduacao}"
vc esta passando um long aqui 
itemValue="#{programas.id}
se não é um long, coloque só
itemValue="#{programas}

Marcos Rodrigues

unread,
Sep 9, 2016, 9:52:16 AM9/9/16
to javasf: JavaServer Faces Group, marcos.ro...@gmail.com
Galera, consegui resolver.

Era realmente um problema no método EQUALS.

Antes, estava assim:
@Override
      public boolean equals(Object obj) {
            if (this == obj) return true;
          if (obj == null) return false;
         if (getClass() != obj.getClass()) return false;
       
                if (obj instanceof ProgramaPosGraduacao) {
                     ProgramaPosGraduacao other = (ProgramaPosGraduacao) obj;
                       
                       return id == other.id
                          && programa == other.programa
                          && modalidade == other.modalidade;
             }
             
                return false;
  }

Eu alterei ele para ficar assim:
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
if (!(obj instanceof ProgramaPosGraduacao)) return false;
if(obj instanceof ProgramaPosGraduacao) {
ProgramaPosGraduacao other = (ProgramaPosGraduacao) obj;
if (this.id == null && other.id != null) return false;
return this.id.longValue() == other.id.longValue()
&& this.programa.equals(other.programa)
&& modalidade.equals(other.modalidade);
}
return false;
}

Basicamente o erro estava sendo no id.longValue(), que eu não estava usando e a minha classe estava usando um tipo Long.

Muito obrigado a todos que ajudaram !
 

Marcos Rodrigues

unread,
Sep 9, 2016, 9:52:16 AM9/9/16
to Jivago Silva, javasf: JavaServer Faces Group
Então, no meu caso o erro foi exatamente no metodo "equals", eu sobrescrevi ele e funcionou. O meu converter sempre estava retornando o objeto e o toString sempre retornando o id do objeto. No equals, a comparação com tipos Long estava errada. Eu comparava this.id == other.id, sendo id uma variavel Long. Quando eu alterei para this.id.longValue() == other.id.longValue(), ele funcionou perfeitamente.

Jivago, o valor é um long sim. Mas mesmo sendo um long, eu coloquei o itemValue="#{programas}", e funcionou !

Atenciosamente,

Marcos Rodrigues.

Analista e Desenvolvedor Freelancer

http://br.linkedin.com/pub/marcos-rodrigues/63/50/300
Reply all
Reply to author
Forward
0 new messages