selectOneMenu - selectItems

A Ação do h:commandButton não está funcionando quando coloco o h:selectOneMenu e o f:selectItems. Porém quando eu os retiro, eles funcionam corretamente.

Oq está acontecendo? Preciso da ajuda de vocês.

<h:panelGrid columns="2">
        
        	<h:outputLabel value="Nome do Setor: " for="nome-setor"/>
			<h:inputText id="nome-setor" required="true" value="#{setorBean.setor.nomeSetor}"/>
	
	
			<h:outputLabel value="Orgão Relacionado: " />
			<h:selectOneMenu value="#{setorBean.setor.orgao}">
				<f:selectItems value="#{setorBean.orgaos}" var="orgao" itemValue="#{orgao.idOrgao}" itemLabel="#{orgao.nomeOrgao}"/>
				<f:ajax event="change" />
			</h:selectOneMenu>
			
	
			<h:commandButton value="Cadastrar Setor" styleClass="botao-formulario">
                <f:ajax event="click" execute="@form" listener="#{setorBean.adiciona}" render="@form"/>
        	</h:commandButton>

</h:panelGrid>

Desde já agradeço a todos que me ajudarem. Obrigado!

No console aparece alguma mensagem de erro?

Não. Eu clico no botão e não acontece nada.

E se vc tirar o <f:ajax event=“change” />?

Não entendi porque foi colocado o <f:ajax event=“change” /> junto com o selectOneMenu.
Tire essa chamada Ajax e teste novamente.

Realmente o Ajax não está fazendo nada neste código. Já retirei ele, mas continua na mesma.

O que você quis dizer quando falou [quote]Porém quando eu os retiro, eles funcionam corretamente.[/quote] ?

O valor de <h:inputText id="nome-setor" required="true" value="#{setorBean.setor.nomeSetor}"/> vai para o ManagedBean?

Prezado bom dia!

Tive alguns problemas no inicio com o selectOneMenu, já olhou o conversor? nas classes de entidade implementou o metodo toString?

Respondendo primeiro ao Willes Reis: Qndo eu retiro os blocos selectOneMenu e selectItems, o botão de cadastro funciona normalmente, mas o Setor é cadastrado no banco sem o atributo Orgão.

O Valor vai para o ManagedBean sim. Pelo menso era para ir(kkkkkkkkkkk).

Respondendo para rlira: Q Conversor? No Início estava mesmo dando uns erros de conversão dos tipos list para selectItem, mas depois funcionou normal.

Eu não implementei nenhum método toString nas entidades. É mesmo necessário? Pq? Se sim, como farei e oq colocarei no método toString implementado?

Poderia enviar o código completo do ManagedBean e da página para eu analisar?

O que é um converter?
Um converter pode ser uma classe java que implemente javax.faces.converter.Converter ou pode-se utilizar tags do próprio jsf

Vou tentar explicar como eu conseguir resolver o problema,
No momento de salvar os dados, o que esta na pagina web são string´s ou seja texto, então o JSF precisa converter isto para objetos então por isto ele chama um conversor, então ele ( o conversor ) deve ser implementado.
o conversor serve tanto no momento de carregar os dados para a pagina, quanto no momento de obter os dados da pagina
para salvar. Para salvar devera ser chamado um método getAsObject
vamos passo a passo então vou começar das classes entidade usando um exemplo de Municipio e Estado

trecho de codigo da classe Municipio.Java mostrando o relacionamento

//bi-directional many-to-one association to Estado  
@ManyToOne(fetch=FetchType.LAZY)  
@JoinColumn(name="id_estado")  
private Estado estado; 

Estado.java

//Observe o metodo toString porque ele será necessário
@Id
@Column(name="id_estado")
private String idEstado;

@Column(name="ds_estado")
private String dsEstado;

//bi-directional many-to-one association to Municipio
@OneToMany(mappedBy="estado")
private List<Municipio> municipios;
@Override
public String toString() {
       return dsEstado;
 }

Vamos agora ver como esta a minha pagina, note que ela chama um metodo estadoC.itemsAvailableSelectOne
“estadoC” é o meu MB

<h:outputLabel for="nome"  value="Nome:" />  
<h:inputText   id="nome"   value="#{municipioC.municipio.dsMunicipio}" style=" width : 450px;"/>              
    
<h:outputLabel  for="estado"  value="Uf:" />     
               
<h:selectOneMenu id="estado"  value="#{municipioC.municipio.estado}" >  
    
   <f:selectItems value="#{estadoC.itemsAvailableSelectOne}"  
      var="item"   
      itemValue="#{item}"   
      itemLabel="#{item.dsEstado}"            />  
</h:selectOneMenu>          

EstadoController.java

@ManagedBean(name="estadoC")  
@SessionScoped  
public class EstadoController {  
      
   private Estado estado;  
   private List<Estado> estadoLista;  
   private int totalRegistros;  
      
   @ManagedProperty(value = "#{estadoService}")  
   private EstadoService estadoService;  

   public SelectItem[] getItemsAvailableSelectOne() {  
          
        return FacesUtil.getSelectItems(estadoService.findAll(), true);  
      
   }   
  
    @FacesConverter(forClass = Estado.class)  
    public static class EstadoControllerConverter implements Converter {  
 
        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {  
            if (value == null || value.length() == 0) {  
                return null;  
            }  
                          
                     
            EstadoController controller = (EstadoController) facesContext.getApplication().getELResolver().  
                    getValue(facesContext.getELContext(), null, "estadoC");  
            return controller.estadoService.findByID(getKey(value));  
        }  

so para não ficar duvidas vamos ver o metodo getSelectItems na classe FacesUtil
observe a variavel X que será o objeto Estado e x.toString() será a descricao do estado ( veja na classe Estado.java )

FacesUtil.java

public static SelectItem[] getSelectItems(List<?> entities, boolean selectOne) {  
    int size = selectOne ? entities.size() + 1 : entities.size();  
    SelectItem[] items = new SelectItem[size];  
    int i = 0;  
    if (selectOne) {  
        items[0] = new SelectItem("", "---");  
        i++;  
    }  
    for (Object x : entities) {  
        items[i++] = new SelectItem(x, x.toString());  
    }  
    return items;  
}