Método sempre retorna null com JSF

3 respostas
Rodrigo_Manhaes

Boa tarde,

utilizo JSF+EJB+JPA e estou enfrentando um problema estranhíssimo. Em um cadastro de horários de uma turma de alunos, é necessário verificar coincidências de horários. Daí criei um método verificaCoincidencia() na classe Turma, que retorna um Map<Horario, Horario> com os pares de coincidências encontrados. Todo o processamento para a verificação é feito no próprio objeto Turma, que já está associado aos horários, não há qualquer consulta ao BD. O método é chamado a partir do MBean.

O problema é o seguinte: a coincidência é encontrada dentro do método, que cria o mapa, atribui o par correto e retorna o mapa. No MBean, contudo, o retorno do método é sempre null. Nos testes de unidade, fora do servidor web, o método funciona perfeitamente, retornando o mapa de modo correto.

Tentamos substituir o retorno passando o mapa por parâmetro e o método também recebe sempre o parâmetro como nulo, mesmo que seja passado um objeto válido.

Alguém tem idéia do que pode ser isto?

3 Respostas

ACDias

Pode passar o código da página JSF?

Rodrigo_Manhaes

Seguem códigos das três partes envolvidas: página, MBean e classe de domínio.

Página
<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:a4j="https://ajax4jsf.dev.java.net/ajax">
    
      <ui:composition template="template-posgrad.xhtml">
          
      <ui:define name="titulo">Cadastro de Turma - Hor&#x00E1;rios</ui:define>
      
      <ui:define name="links">
          <script type="text/javascript" src="/posgrad/script/mascaras.js"></script>
      </ui:define>
      
      <ui:define name="conteudo">
          
        <h:panelGroup rendered="#{!empty turma.turma.horarios}">
            <p>
                <h:dataTable value="#{turma.horariosDataModel}" var="horario">
                    
                    <h:column>
                        <f:facet name="header">
                            <h:outputText value="Dia"/>
                        </f:facet>
                        <h:outputText value="#{horario.diaSemana}"/>
                    </h:column>
                    
                    <h:column>
                        <f:facet name="header">
                            <h:outputText value="In&#x00ED;cio"/>
                        </f:facet>
                        <h:outputText value="#{horario.horaInicio}"/>
                    </h:column>
                    
                    <h:column>
                        <f:facet name="header">
                            <h:outputText value="T&#x00E9;rmino"/>
                        </f:facet>
                        <h:outputText value="#{horario.horaTermino}"/>
                    </h:column>

                    <h:column>
                        <h:commandLink value="Alterar" action="#{turma.editarHorario}" immediate="true"/>
                    </h:column>
                    
                    <h:column>
                        <h:commandLink value="Excluir" action="#{turma.excluirHorario}" immediate="true"/>
                        <h:panelGroup rendered="#{turma.excluindoHorario}">
                                <label>Confirma?</label>
                                <h:commandButton value="Sim" action="#{turma.confirmarExclusaoHorario}" immediate="true"/>
                                <h:commandButton value="N&#x00E3;o" action="#{turma.cancelarExclusaoHorario}" immediate="true"/>
                        </h:panelGroup>
                    </h:column>
                    
                </h:dataTable>    
            </p>
            
        </h:panelGroup>
    
        <p>
            <a jsfc="h:commandLink" value="Novo Hor&#x00E1;rio" action="#{turma.incluirHorario}"/>
        </p>
        
        <p>
            <a jsfc="h:commandLink" value="Retornar &#x00E0; tela anterior" action="cadastrarTurma" immediate="true"/>
        </p>
        
        <h:panelGroup rendered="#{!empty turma.horarioDaVez}">
            <fieldset>
                
                <p>
                    <label jsfc="h:outputLabel" for="diaSemana">Dia da semana</label>
                    <select jsfc="h:selectOneMenu" id="diaSemana" value="#{turma.diaSemana}">
                        <option jsfc="f:selectItems" value="#{pato.diasSemanaItem}"/>
                    </select>
                </p>
                
                <p>
                    <label jsfc="h:outputLabel" for="horaInicio">Hora in&#x00ED;cio</label>
                    <input jsfc="h:inputText" type="text" id="horaInicio" maxlength="5"
                        size="5" value="#{turma.horarioDaVez.horaInicio}"
                        required="true" requiredMessage="A hora de in&#x00ED;cio &#x00E9; obrigat&#x00F3;ria"
                        onkeypress="mascaraHora(this, event)"/>
                </p>
                
                <p>
                    <label jsfc="h:outputLabel" for="horaTermino">Hora t&#x00E9;rmino</label>
                    <input jsfc="h:inputText" type="text" id="horaTermino" maxlength="5"
                        size="5" value="#{turma.horarioDaVez.horaTermino}"
                        required="true" requiredMessage="A hora de t&#x00E9;rmino &#x00E9; obrigat&#x00F3;ria"
                        onkeypress="mascaraHora(this, event)"/>
                </p>
    
                <p>
                    <a jsfc="h:commandLink" value="Registrar" action="#{turma.salvarHorario}"/>
                </p>
                
            </fieldset>
            
        </h:panelGroup>
            
      </ui:define>
          
      </ui:composition>
    
</html>
O último link da página chama o método salvarHorario do MBean, transcrito abaixo:
@SuppressWarnings("unchecked")
public String salvarHorario()
{
    List<Horario> lista = (List) horariosDataModel.getWrappedData();
    if (horarioDaVez.getId() == null) // incluindo
    {
        lista.add(horarioDaVez);
        turma.adicionaHorario(horarioDaVez);
    }
    horarioDaVez.setDiaSemana(diaSemana);
    
    Map<Horario, Horario> concidencias = turma.verificaCoincidencias();
    
    // TODO quando o problema do retorno for resolvido, remover o teste por nulo
    if (coincidencias != null && coincidencias.size() > 0)
    {
        Horario horarioCoincidente = null;
        if (coincidencias.containsKey(horarioDaVez))
            horarioCoincidente = coincidencias.get(horarioDaVez);
        else
        {
            for (Horario horario: coincidencias.keySet())
                if (coincidencias.get(horario).equals(horarioDaVez))
                {
                    horarioCoincidente = horario;
                    break;
                }
        }
            
        JSFUtils.mostrarMensagem(
            new StringBuilder()
                .append("Este hor\u00E1rio \u00E9 coincidente com o hor\u00E1rio de ")
                .append(horarioCoincidente.getHoraInicio())
                .append(" \u00E0s ")
                .append(horarioCoincidente.getHoraTermino())
                .append(" n")
                .append(horarioCoincidente.getDiaSemana().getArtigo())
                .append(" ")
                .append(horarioCoincidente.getDiaSemana())
                .append(".")
            .toString());
            
        return "paginaTurmaHorario";
    }
        
    Collections.sort(lista, Horario.getHorarioComparator());
    horariosDataModel.setWrappedData(lista);
      
    horarioDaVez = null;
        
    return "paginaTurmaHorario";
}
Abaixo, o código do método verificarCoincidencias() na classe Turma
public Map<Horario, Horario> verificaCoincidencias()
{
    Map<Horario, Horario> coincidencias = new HashMap<Horario, Horario>();

    // se a disciplina nao exige verificacao de horario, retorna mapa vazio
    if (this.getDisciplina() != null && this.getDisciplina().getNaoVerificaCoincidencia())
        return coincidencias;
        
    List<Horario> horarios = new ArrayList<Horario>(this.getHorarios());
    for (int i = 0; i < horarios.size() - 1; i++)
    {
        Horario horario = horarios.get(i);
            
        for (int j = i+1; j < horarios.size(); j++)
        {
            Horario horario2 = horarios.get(j);
            if (!horario.getDiaSemana().equals(horario2.getDiaSemana()))
                continue;
                
            boolean horaInicio1MenorQueHoraInicio2 = horario.getHoraInicio().compareTo(horario2.getHoraInicio()) < 0;
            boolean horaTermino1MenorOuIgualAHoraInicio2 = horario.getHoraTermino().compareTo(horario2.getHoraInicio()) <= 0;
            boolean horaInicio1MaiorOuIgualAHoraTermino2 = horario.getHoraInicio().compareTo(horario2.getHoraTermino()) >= 0;
            boolean horaTermino1MaiorQueHoraTermino2 = horario.getHoraTermino().compareTo(horario2.getHoraTermino()) > 0;
                
            if (!
                ((horaInicio1MenorQueHoraInicio2 && horaTermino1MenorOuIgualAHoraInicio2)
                ||
                (horaInicio1MaiorOuIgualAHoraTermino2 && horaTermino1MaiorQueHoraTermino2)))
            {
                coincidencias.put(horario, horario2);
            }
        }
    }
        
    return coincidencias;
}

O método funciona perfeitamente nos testes de unidade. Porém, quando roda no servidor (Glassfish), retorna sempre null. Durante a depuração, o conteúdo do mapa se mostra um objeto válido até o retorno do método. No MBean, porém, o retorno é sempre nulo.

Agradeço qualquer ajuda.

GabrielCardelli

Estou com o mesmo problema, alguem pode me ajudar?

Abraço.

(Eu sei que o tópico é antigo, sem flood)

Criado 13 de agosto de 2007
Ultima resposta 20 de jan. de 2011
Respostas 3
Participantes 3