Pesssoal,
Estou utilizando jsf2 e estou com um problema:
Tenho uma lista de empresas no meu select. Gostaria que no evento change do select, ao selecionar outra empresa, alterasse o valor da variavel empresa no bean.
Olha como está :
No xhtml está assim
<h:selectOneMenu value="#{meuBean.empresa}" styleClass="xxlarge " >
<f:selectItems value="#{meuBean.empresas}" var="empresa" itemValue="#{empresa}" itemLabel="#{empresa.razaoSocial}"/>
<f:ajax event="change" immediate="true" listener="#{meuBean.alterarEmpresa(empresa)}"/>
</h:selectOneMenu>
E no ManagedBean do java está:
public void alterarEmpresa(Empresa e) {
if (e != null ) {
System.out.println("Teste1");
} else {
System.out.println("Teste2");
}
}
Porém o valor da empresa sempre vem como null…
Eu ja li varios posts mas nenhum me ajudou, tentei alterar direto a variavel no bean sem precisar passar por parametro mas também nao deu certo… Alguém pode me ajudar?
Tentei de todas formas possiveis e impossíveis e descobri o seguinte:
Como eu estava passando uma lista de objetos do tipo empresa o JSF não setava o objeto no onchange, nao sei se é uma limitação do JSF, mas pelo que andei lendo , devo utilizar um Converter ou entao passar uma lista de Strings.
Ao passar uma lista de String funcionou da forma mais simples possível:
<f:ajax event="change" immediate="true" listener="#{meuBean.selecionarEmpresa()}" >
<h:selectOneMenu value="#{meuBean.empresaSelecionada}" id="empresa" styleClass="xxlarge " >
<f:selectItems value="#{meuBean.listaEmpresas}" var="empresa" itemValue="#{empresa}" />
</h:selectOneMenu>
</f:ajax>
O Pior é que não recebima nenhum log ou msg de erro…
Algumas mensagens são suprimidas pelo JSF se o sistema estiver em produção, para mostrar mensagens a mais no desenvolvimento, é necessário adicionar um parâmetro no seu web.xml <context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
Valeu pela dica Digao mas agora estou com outro problema:
Puxa vida…
Com Lista de String funcionou certinho, o problema é que eu preciso realmente da lista de objetos do tipo empresa.
Estou fazendo um converter e debugando,
Quando eu seleciono uma empresa ele chama o metodo getAsObject do converter e retorna a empresa que eu selecionei…
O problema é que eu nao sei pra onde ele retorna pq esse valor nao vai para nenhum lugar!
Eu gostaria que fosse para o objeto empresa dentro do meu bean, mas ele nao chama o set
o xhtml esta assim:
<f:ajax event="change" immediate="true" listener="#{cadastrarColetorSamasBean.selecionarEmpresa()}" >
<h:selectOneMenu value="#{cadastrarColetorSamasBean.empresa}" id="empresa" styleClass="xxlarge " >
<f:selectItems value="#{cadastrarColetorSamasBean.empresas}" var="empresa" itemValue="#{empresa}" itemLabel="#{empresa.razaoSocial}" />
</h:selectOneMenu>
</f:ajax>
No managed bean:
// CAMPOS EMPRESA
public Empresa getEmpresa() {
return empresa;
}
public void setEmpresa(Empresa empresa) {
this.empresa = empresa;
}
// Método realizado ao alterar o select
public String selecionarEmpresa() {
Logger.getLogger(CadastrarColetorSamasBean.class.getName()).log(Level.INFO, "Empresa selecionada::: {0}", empresa.getIdEmpresa());
return null;
}
//Popular Combo de Empresa
public List<Empresa> getEmpresas() throws ClassNotFoundException, SQLException {
List<Empresa> listaEmpresasSelect = new ArrayList();
if (this.empresas == null) {
List<Empresa> empresas = coletorSamasService.popularListaEmpresas();
for (Empresa e : empresas) {
listaEmpresasSelect.add(new Empresa(e.getIdEmpresa(), e.getRazaoSocial()));
}
}
return listaEmpresasSelect;
}
E o Converter:
@FacesConverter(forClass = Empresa.class)
public class EmpresaConverter implements Converter {
private EmpresaDao daoEmpresa;
public EmpresaConverter() throws NamingException {
daoEmpresa = new EmpresaDao();
}
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value != null && value.trim().length() > 0) {
int id = Integer.valueOf(value);
return daoEmpresa.getEmpresaById(id);
}
return null;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value != null) {
Empresa empresa = (Empresa) value;
return empresa.getIdEmpresa().toString();
}
return "";
}
Alguém sabe para onde está sendo retornado a empresa retornada pelo getAsObject do Converter?
ele deveria ir para o atributo setado como value do seu <h:selectOneMenu>
Pois é!!! Pior que não vai 
Tente assim:<h:selectOneMenu value="#{cadastrarColetorSamasBean.empresa}" id="empresa" styleClass="xxlarge " >
<f:selectItems value="#{cadastrarColetorSamasBean.empresas}"
var="empresa" itemValue="#{empresa}" itemLabel="#{empresa.razaoSocial}" />
<f:ajax event="change" render="@this" execute="@this" listener="#{cadastrarColetorSamasBean.selecionarEmpresa()}" />
</h:selectOneMenu>
O que faz esse seu listener?
Hoje o listener tem apenas um logger que eu coloquei um break point para ver se está sendo chamado no on change.
Ao debugar eu vejo que o método selecionarEmpresa() do bean está sendo chamado.
Depois dele ser chamado é chamado o getAsObject do Converter que retorna a empresa corretamente mas essa empresa nao é setada no setEmpresa() do Bean como o esperado.
Depois do getAsObject do Converter que retorna uma empresa que nao é setada em lugar nenhum é chamado o metodo getEmpresas do mesmo Bean para carregar a lista de empresas. E também nesse momento eu verifico o valor da propriedade empresa, e está null. 
Acredito que se eu der um submit o valor deverá ir para o Bean, vou fazer o teste… O problema é q eu gostaria de alterar o valor no onChange …
Isso é perfeitamente possível, eu sempre fiz assim, só não sei se está havendo algum conflito com seu listener, você ja experimentou remover ele? Somente a tag ajax que eu coloquei no exemplo, sem o listener, sempre resolveu o problema pra mim.
Valeu Rodrigo pelas dicas!!
Nao sei porque cargas d’agua o converter nao setava o valor da empresa no bean entao resolvi fazer de uma maneira bem simples
Passo uma lista de empresas para o select.
Ao selecionar passo o id da Empresa para o Managed Bean, ao invés de passar o objeto empresa, e assim o proprio Managed bean faz o papel do converter, ou seja
ele mesmo busca a empresa referente aquele id.
Assim deu certo
No xhtml
<h:selectOneMenu id="combo-empresa" value="#{solicitarColetorSamasBean.idEmpresaSelecionada}" >
<f:ajax event="change" render="@form" listener="#{solicitarColetorSamasBean.atualizaEmpresa}" />
<f:selectItems value="#{solicitarColetorSamasBean.empresas}"
var="empresa"
itemValue="#{empresa.idEmpresa}"
itemLabel="#{empresa.razaoSocial}" />
</h:selectOneMenu>
No ManagedBean
public void atualizaEmpresa() {
if (idEmpresaSelecionada != null) {
Empresa e = (Empresa) coletorSamasService.getEmpresaById(idEmpresaSelecionada);
coletorSamas.setEmpresa(e);
}
}