problema com projeto em JSF 1.2

07/09/2010

Estou realizando meu trabalho de conclusão de curso, fazendo um sistema para controle de entrada e saída de hospedes de um motel (SISMOT) utilizando as seguintes tecnologias/Ferramentas: Hibernate; Java Server Faces 1.2; NetBeans 6.9.1. Criei uma interface chamada CrudDAO segue link do codigo: http://paste-it.net/public/x2281c1/

Logo em seguida criei uma classe chamada CrudDAOJPA que implementa esta interface. link do codigo: http://paste-it.net/public/t8fa433/

Nesta classe implemento e realizo a codificação dos seguintes metodos:
void alterarEntidade();void salvarEntidade();void excluirEntidade();T buscarPorId();List<T> buscarTodos();
Em meu pacote br.com.sismot.model.dao.impl, tenho a classe CategoriaQuartoDAOImpl e QuartoDaoImpl que extendem e implementam estes metodos.

Na minha view tenho quatro links:
Cadastrar categorias;Consultar categorias;Cadastrar quartos;Consultar quartos;Ao chamar o link Consultar categorias chamo meu bean CadastroCategoriaBean, nesta classe crio uma instancia de minha CategoriaQuartoDaoImpl a fim de realizar as chamadas aos metodos implementados por ela atraves da extensao da Classe CrudDAOJPA<T>.

Segue link da classe: http://paste-it.net/public/y810abd/

Ao executar o metodo buscarTodos() apos a chamada do link ConsultarCategorias tenho o seguinte erro. Segue link:

http://paste-it.net/public/z880100/

No link cadastrarQuarto, ele carrega um formulario onde tenho um selectItem que traz as informações cadastradas no banco referentes as categorias do quarto, como estou com um erro neste metodo. Ele não carrega o selectItem gerando um erro ao carregar o formulario.

Quero Corrigir o metodo buscarTodos e deixa - lo generico, onde eu possa implementar varias DAO e ele realizar um Select * from <NomeDaClasse> para qualquer classe que o implemente.

 public List<T> buscarTodos() throws DAOException {
        Session session = HibernateUtil.getSession();
        try {
            //Corrigir esta linha do codigo
            Query listaQuartos = session.createQuery("from "+this.classEntity.getClass().toString());
            session.beginTransaction().commit();
            return listaQuartos.list();
        } catch (Exception e) {
            session.beginTransaction().rollback();
            throw new DAOException(e);
        } finally{
            //implementar metodo para fechar conexão no hibernate Util
        }
    }

Como faço para corrigir este problema?

Segue abaixo o link para acessar os codigos fontes do projeto

links
src:     http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/classes/src-2.rar
web:     http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/web/web.rar
telas: http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/telas/telas.rar

Marcos Sousa

Marcos Sousa

Curtidas 0

Respostas

Henrique Weissmann

Henrique Weissmann

07/09/2010

Marcos,

o problema que você está enfrentando está na linha que marquei no seu código

public List<T> buscarTodos() throws DAOException {
Session session = HibernateUtil.getSession();
try {
//Corrigir esta linha do codigo
(erro) Query listaQuartos = session.createQuery("from "+this.classEntity.getClass().toString());
session.beginTransaction().commit();
return listaQuartos.list();
} catch (Exception e) {
session.beginTransaction().rollback();
throw new DAOException(e);
} finally{
//implementar metodo para fechar conexão no hibernate Util
}
}
classEntity é o tipo Class da classe que você definiu com o método setClassEntity na classe CrudDAOJPA. Quando você chama o método getClass() deste atributo, vai sempre obter um resultado do tipo java.lang.Class, e não o tipo que você havia definido

Neste caso, se o atributo ainda não tiver sido setado, você vai se deparar com uma excessão do tipo NullPointerException.

Caso já tenha sido setado, vai topar com uma consulta cujo texto será
"from java.lang.Class", que não vai fazer sentido para o Hibernate. A solução pro problema então é simples.

Reescreva a linha problemática para que fique tal como no exemplo abaixo:

Query listaQuartos = session.createQuery("from " + classEntity.getName());

O método getName vai te retornar o nome completo da classe.

Voltando ao seu método buscarTodos, você pode também evitar o NullPointerException adicionando o seguinte código logo no seu início:

if (this.classEntity == null) {
   // dispare uma excessão ou simplesmente retorne null.
}
GOSTEI 0
Marcos Sousa

Marcos Sousa

07/09/2010

Boa noite. Fiz a alteração que voce sugeriu, mais ao realizar a consulta ele me retornou um java.lang.nullPointerException, so não fiz o tratamento do classEntity com um if como sugerido passando o erro a uma exeção.

Detalhe do codigo alterado
public List<T> buscarTodos() throws DAOException {
Session session = HibernateUtil.getSession();
try {
//Corrigir esta linha do codigo
Query listaQuartos = session.createQuery("from "+classEntity.getName());
session.beginTransaction().commit();
return listaQuartos.list();
} catch (Exception e) {
session.beginTransaction().rollback();
throw new DAOException(e);
} finally{
//implementar metodo para fechar conexão no hibernate Util
}
}



Segue link do código alterado.

http://paste-it.net/public/d067ebb/

Desde já agradeço pelo apoio.
GOSTEI 0
Henrique Weissmann

Henrique Weissmann

07/09/2010

Marcos, algumas sugestões dando uma olhada no seu código ok? 1. Nullpointer exception acontece quando acessamos métodos ou atributos de uma variável que aponta para uma classe que ainda não foi instanciada. Observando o seu código fonte, temos um suspeito: a variável session. 2. Solução: pode ser que você não esteja conseguindo instanciar o SessionFactory direito. Faça o seguinte: crie um teste unitário para a classe HibernateUtil que verifique se o método getSession() está retornando uma session para você de fato. Normalmente problemas na configuração do Hibernate impedem a criação do sessionFactory e, consequentemente, topamos com estes problemas. Se estiver usando o Netbeans, a criação de testes unitários é super simples. Basta usar o atalho Ctrl + Shift + U com a classe HibernateUtils aberta no editor. Ele irá criar um esqueleto do teste unitário, com um teste para cada método público da classe em questão. Verifique se há algum stacktrace na instanciação do SessionFactory e em seguida nos retorne este caso ocorra ok?
GOSTEI 0
Marcos Sousa

Marcos Sousa

07/09/2010

Boa tarde. Criei a classe de teste conforme voce me pediu, mais na hora de realizar o teste tive uma dúvida. Não entendi o que devo fazer. Segue o link da classe de teste criada.

http://paste-it.net/public/v5970d6/

Ao gerar a classe fiz estas modificações e criei um metodo chamado sessao(). Segue abaixo alteração feita

 SessionFactory sessionFactory;

 //O construtor default estava vazio
    public HibernateUtilTest() {
        sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
        sessionFactory.openSession();
    }

//metodo sessao
 public Session sessao(){
        return sessionFactory.openSession();
    }

O metodo getTestSession gerado pelo JUNIT inicialmente veio assim

@Test
    public void testGetSession() {
        System.out.println("getSession");

        Session expResult =  null;
        Session result = HibernateUtil.getSession();

        assertEquals(expResult, result);
        // TODO review the generated test code and remove the default call to fail.
       fail("The test case is a prototype.");

Ao compilar estarei comparando o argumento expResult que e nulo com o argumento result HibernateUtil.getSession() que em principio deve me retornar uma conexão. Esta e minha dúvida o que devo colocar no atributo expResult para que ele passe no teste?

Segue link do disco virtual com a tela do resultado do test do JUnit

http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/telaJUnit.rar

Segue link com os .JAR do projeto
http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/src-2.rar

Henrique desde já agradeço.
GOSTEI 0
Henrique Weissmann

Henrique Weissmann

07/09/2010

Marcos,

o teste unitário servirá para detectar se você está com problemas na hora de obter a sua sessão do Hibernate.

O framework JUnit nos fornece diversos métodos para que possamos criar os nossos testes. Sendo assim, o teste que você criou para o método getSession() da sua classe pode ser modificado. Vou lhe mostrar como fazê-lo, mas antes, vou comentar o seu código de teste ok?

*/
@Test
public void testGetSession() {
System.out.println("getSession");
Session expResult = new HibernateUtilTest().sessao();
Session result = HibernateUtil.getSession();

assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
// fail("The test case is a prototype.");
}


O que ocorre: o método assertEquals é usado para verificar se os dois valores passados para a função possuem
o mesmo valor. O Junit fará esta verificação chamando o método equals de cada um dos objetos
passados como parâmetro.

No seu caso, no entanto, você não precisa testar se são iguais, mas sim se algo está sendo
retornado.

Então, tudo o que você precisaria fazer seria reescrever o seu teste unitário usando a função assertNotNull
fornecida pelo JUnit, tal como no exemplo abaixo:



*/
@Test
public void testGetSession() {
System.out.println("getSession");
Session expResult = HibernateUtil().getSession();
assertNotNull(expResult);
}
*/

Caso seja retornado null, é sinal de que o erro de NullPointerException que você está tendo tem
sua origem na obtenção do SessionFactory do Hibernate.


Dica: você pode depurar testes unitários pelo Netbeans. Para isto, basta usar a combinação de teclas
Ctrl + Shift + F6. Assim, caso não esteja conseguindo obter o SessionFactory, terá como descobrir
a causa do problema e, ainda mais interessante, nos passar os dados para que possamos sanar
este problema.
GOSTEI 0
Marcos Sousa

Marcos Sousa

07/09/2010

Boa noite Henrique. Fiz as correções que voce me sugeriu no teste da conexão e obtive 100% como resultado. Neste caso então o erro estara no seguinte metodo da classe CRUDDAOJPA

 public List<T> buscarTodos() throws DAOException {
        Session session = HibernateUtil.getSession();
        try {
            //Corrigir esta linha do codigo
           //O objeto classEntity esta vindo nulo e gera um nullPointerException
            Query listaQuartos = session.createQuery("from "+classEntity.getName());
            session.beginTransaction().commit();
            return listaQuartos.list();
        } catch (Exception e) {
            session.beginTransaction().rollback();
            throw new DAOException(e);
        } finally{
            //implementar metodo para fechar conexão no hibernate Util
        }
    }

Agradeço pela ajuda para verificação do erro da conexão com o JUNIT.
GOSTEI 0
Henrique Weissmann

Henrique Weissmann

07/09/2010

Marcos, observei outro ponto interessante neste seu código. Faça o seguinte: inicie a transação antes de criar o objeto Query. Agora, já vi ocorrerem casos em que a transação associada a uma consulta gera problemas em algumas versões muito específicas do Hibernate. Tente fazer a mesma consulta sem transação e me diga o resultado ok?
GOSTEI 0
Marcos Sousa

Marcos Sousa

07/09/2010

Boa tarde Henrique. Fiz as duas sugestões que voce me orientou mais a consulta ainda ao final está me retornando nullPointerException.   Envio o link do metodo alterado com o transaction antes da Query http://paste-it.net/public/vd8cd9e/ E o metodo alterado com o transaction sem o begin transaction http://www.paste-it.net/public/jfb6d45/  
GOSTEI 0
Henrique Weissmann

Henrique Weissmann

07/09/2010

Marcos,

o ponto aonde o NullPointerException pode ocorrer é nesta linha:

Query listaQuartos = session.createQuery("from "+classEntity.getName());


Sugestão:
há um problema neste trecho.

catch (Exception e) {
session.beginTransaction().rollback();
throw new DAOException(e);
}

Se você iniciar uma transação logo após ter sido executada a operação, e em seguida der um rollback, será a mesma
coisa que nada. Sendo assim, visto que a transação foi removida, substitua este catch pelo código abaixo

catch (Throwable e) {
e.printStackTrace();
throw new DAOException(e);
}
Substitui por throwable porque se houver algum erro de runtime, você o interceptará.
o printStackTrace irá expor em qual linha exatamente está ocorrendo o NullPointerException.

E a transação foi removida por ser desnecessária.
GOSTEI 0
Marcos Sousa

Marcos Sousa

07/09/2010

Boa tarde Henrique, fiz as alterações que voce me sugeriu mais o metodo continua retornando nullPointerException

 public List<T> buscarTodos() throws DAOException {
        Session session = HibernateUtil.getSession();
        try {
            //Corrigir esta linha do codigo
            Query listaQuartos = session.createQuery("from "+classEntity.getName());
            session.beginTransaction().commit();
            return listaQuartos.list();
       
  } catch (Throwable e) {
            e.printStackTrace();
            throw new DAOException(e);
      
 } finally{
            //implementar metodo para fechar conexão no hibernate Util
          
        }
    }

No debug do projeto ele não me retorna nenhum valor para o atributo classEntity, neste caso eu tenho a necessidade de criar um persist.xml para que eu tenha uma unidade de persistencia e consiga retornar o nome da classe?

GOSTEI 0
Henrique Weissmann

Henrique Weissmann

07/09/2010

Oi Marcos, pelo que pude ver, você não ai precisar alterar nada nos seus arquivos de configuração, mas sim no modo como a sua classe está sendo instanciada/construída. Verifique qual o caminho completo que leva à definição do atributo classEntity. Talvez a instanciação/construção desta classe esteja dependendo de uma sequencia de ações que, ao ser executada fora do contexto inicial (num teste unitário por exemplo), não esteja preenchendo este atributo. Sugestão: na sua classe básica, aonde este atributo é definido, obrigue o preenchimento deste atributo através da criação de um construtor customizado OU através da criação de um getter abstrato que obrique sua implementação nas classes filhas.
GOSTEI 0
Marcos Sousa

Marcos Sousa

07/09/2010

Henrique infelizmente não consegui entender e compreender bem a sua mensagem. Mesmo assim fiz algumas mudanças e queria ver com voce se o raciocinio era este.

Sua resposta: "Sugestão: na sua classe básica, aonde este atributo é definido, obrigue o preenchimento deste atributo através da criação de um construtor customizado OU através da criação de um getter abstrato".

Minha ação. no pacote br.com.sismot.model.dao.commons

Classe CrudDAOJPA<T> implements CrudDAO<T> criei um construtor que recebe como parametro um objeto do tipo Class<T> classEntity

ver codigo da classe: http://paste-it.net/public/u989c8f/

Em seguida no pacote package br.com.sismot.model.dao.impl; onde se encontra minha classe CategoriaQuartoDAOImpl tenho como atributo o objeto

 private CategoriaQuarto categoriaQuarto;

e gerei o construtor desta classe chamando o super construtor

 public CategoriaQuartoDAOImpl(Class<CategoriaQuarto> classEntity) {
        super(classEntity);
    }

na minha managedBean CategoriaQuartoBean encontrada dentro do pacote br.com.sismot.model.managedBean;

fiz a seguinte alteração no metodo consultarCategorias()

 public String consultarCategorias() throws DAOException {

     //ao instanciar a classe categoriaQuartoDAOImpl ele passo como parametro a CategoriaQuarto.class
       categoriaQuartos = new CategoriaQuartoDAOImpl(CategoriaQuarto.class).buscarTodos();
//        categoriaQuartos = new CategoriaQuartoDAOImpl().listarCategoria();
        if(categoriaQuartos.size() > 0){
            return "listaCategoria";
        }else{
            return "msgCategoria";
        }
       
    }

Agora ao executar o metodo consigo completar a Query e retornar os valores para a consulta.

Pelo que te expliquei seria isto mesmo a ser feito?.

Neste caso tenho o retorno de um List de objetos e com o hibernate se eu quiser ter o retorno de apenas um objeto realizado em uma pesquisa/ consulta qual método utilizaria para isso. Pois com JPA posso utilizar o seguinte metodo

public T findById(Serializable id) throws DAOException {
        EntityManager manager = factory.createEntityManager();
        try {

            //metodo find com hibernate tenho algum método semelhante?
            return manager.find(classEntity, id);
        } catch (Exception e) {
            throw new DAOException(e);
        } finally {
            if (manager != null) {
                manager.close();
            }
        }
    }

Desde já agradeço e segue os links do projeto no disco virtual para analise

http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/classes/src_3.rar
http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/web/web_3.rar

Desde já agradeço.





GOSTEI 0
Henrique Weissmann

Henrique Weissmann

07/09/2010

Oi Marcos,

sim, é exatamente isto que você acabou de fazer. Assim não há como, pelo menos nesta parte do seu código, você topar com um NullPointerException.

Após esta modificação, o problema foi resolvido ou pelo menos reduzido?
GOSTEI 0
Marcos Sousa

Marcos Sousa

07/09/2010

Henrique em relação a otimização da consulta dos dados cadastrados atualmente tenho o seguinte método que realiza uma consulta

 public List<T> buscarTodos() throws DAOException {
        Session session = HibernateUtil.getSession();
        try {
            //Corrigir esta linha do codigo
            Query listaQuartos = session.createQuery("from "+classEntity.getName());
            session.beginTransaction().commit();
            return listaQuartos.list();
          } catch (Throwable e) {
            e.printStackTrace();
            throw new DAOException(e);
        } finally{
            //implementar metodo para fechar conexão no hibernate Util
          
        }
    }

Ele me retorna um List com vários objetos, mais em algumas funções em meu formulário não é necessário retornar um List, só um objeto e suficiente para isto. Tenho um exemplo em JPA que realiza isso:
 
public T findById(Serializable id) throws DAOException {
        EntityManager manager = factory.createEntityManager();
        try {

            //metodo find com hibernate tenho algum método semelhante?
            return manager.find(classEntity, id);
        } catch (Exception e) {
            throw new DAOException(e);
        } finally {
            if (manager != null) {
                manager.close();
            }
        }
    }

Como implemento um método semelhante a este em hibernate que me retorne um objeto? O JPA utiliza o metodo <EntityManager> m.find(classEntity, id).

Desde já agradeço.
 
GOSTEI 0
Henrique Weissmann

Henrique Weissmann

07/09/2010

Oi Marcos,

Vou lhe mostrar duas formas de obter uma instância de uma classe baseada no seu id. Para ambos os casos, vamos imaginar que exista um método em nossa classe que nos retorne uma nova instância de org.hibernate.Session ok? Chamaremos este método de getSession(). Nestes exemplos, irei supor que a chave primária seja do tipo String. Porém o mesmo pode ser aplicado para inteiros, BigDecimal, e qualquer outra classe que implemente a interface java.ioSerializable ou tipo primitivo ok?


Primeira possibilidade. Chamando o próprio método load da classe Session.


public Object getEntidade(Class classe, String id) throws ErroDAO {
   Session sessao = null;
   try {
      sessao = getSession();
      return sessao.load(classe, id); // passo a classe e o identificador para session e ele me retornará um objeto já populado
    } catch (org.hibernate.ObjectNotFoundException ex) {
         //pode ser disparado caso não exista o registro
         return null;
    } catch (Exception ex) {
         throw new ErroDAO(ex);
    } finally {
         if (sessao != null && sessao.isOpen()) {
             sessao.close();
         }
    }
}


Outra possibilidade é usando a API Criteria do Hibernate, tal como no exemplo abaixo. Repare: é a mesma assinatura de método.

public Object getEntidade(Class classe, String id) throws ErroDAO {
   Session sessao = null;
   try {
      sessao = getSession();
      Criteria busca = sessao.createCriteria(classe);
      // Suponho aqui que você tenha padronizado um atributo chamado id para identificar a chave primária
      busca.add(Expression.eq("id", id));
      return busca.uniqueResult();
    } catch (org.hibernate.ObjectNotFoundException ex) {
         //pode ser disparado caso não exista o registro
         return null;
    } catch (Exception ex) {
         throw new ErroDAO(ex);
    } finally {
         if (sessao != null && sessao.isOpen()) {
             sessao.close();
         }
    }
}
GOSTEI 0
Marcos Sousa

Marcos Sousa

07/09/2010

Boa tarde Henrique. Tentei implementar seus dois métodos sugeridos mais não obtive sucesso.

O primeiro a ser realizada a tentativa foi o utilizando o método load do Hibernate

public Carro getEntidade(Carro carro, String placa) throws DAOException{
        Session session = HibernateUtil.getSession();
        try {
            //Nesta linha o IDE me retorna este erro : incompatible types
               required: br.com.sismot.model.entity.Carro
               found:    void
            return session.load(carro, placa);
      
        } catch (org.hibernate.ObjectNotFoundException e) {
            return null;
        } catch(Exception ex){
            throw new DAOException(ex);
        }finally{

        }

    }

Utilizando a segunda sugestão com Criteria

public Carro getEntidadeH(Carro carro, String placa) throws DAOException{
        Session session = HibernateUtil.getSession();
        try {
            Criteria busca = session.createCriteria(carro.getClass());
            busca.add(Expression.eq("placa", placa));
            return (Carro) busca.uniqueResult();
        } catch (org.hibernate.ObjectNotFoundException e) {
            return null;
        } catch(Exception ex){
            throw new DAOException(ex);
        }finally{

        }

    }

Não consegui fazer o que preciso. Tenho uma pagina chamada "FORMALUGUELQUARTO.JSP" onde tenho um campo para pesquisa

                 <tr>
                     <td><h:inputText value="#{alugaQuartosBean.carro.placa}"/>
                        <h:commandButton value="Pesquisar placa" action="#{alugaQuartosBean.consultarPlaca}"/></td>
                </tr>
                <tr>
                    <td><h:outputText value="Placa" />
                      <!-- Campo para retorno da pesquisa -->
                        <h:inputText value="#{alugaQuartosBean.carro.placa}" />
                    </td>
                                                      
                </tr>

Quero preecher o numero da placa neste campo e submeter este valor a minha classe QuartosAlugadosBean que se encontra no managedBean que chama a execução do método getEntidade criado na DAO. Só que ao realizar a consulta o campo String vai nulo para o método implementado na DAO.

Metodo do managedBean

 public Carro getEntidadeH(Carro carro, String placa) throws DAOException{
        Session session = HibernateUtil.getSession();
        try {
            Criteria busca = session.createCriteria(carro.getClass());
            busca.add(Expression.eq("placa", placa));
            return (Carro) busca.uniqueResult();
        } catch (org.hibernate.ObjectNotFoundException e) {
            return null;
        } catch(Exception ex){
            throw new DAOException(ex);
        }finally{

        }

    }


Como devo fazer para preencher este campo e enviar o dado preenchido para a consulta? Tentei fazer assim mais foi gerado um erro:

MANAGEDBEAN

 public String consultarPlaca() throws DAOException{
       
//        carros =  carroDAOImpl.buscarPlaca(carro);
        //Utilizando criteria do hibernate
       carro = carroDAOImpl.getEntidadeH(carro, carro.getPlaca());

        //Utilizando o metodo load do hibernate
//        carro = carroDAOImpl.getEntidade(carro, placa);

        if(carro.equals(null)){
            return "falhaPlaca";
        } else{
            return "sucessoPlaca";
        }
       
    }



DAO
 public Carro getEntidade(Carro carro, Carro placa) throws DAOException{
        Session session = HibernateUtil.getSession();
        try {

             //incompatible types
            required: br.com.sismot.model.entity.Carro
             found:    void
             return session.load(carro, placa.getPlaca());
        } catch (org.hibernate.ObjectNotFoundException e) {
            return null;
        } catch(Exception ex){
            throw new DAOException(ex);
        }finally{

        }

    }


codigos

formAluguelQuarto.jsp: http://paste-it.net/public/ea83122/;
QuartosAlugadosBean: http://paste-it.net/public/y7491b1/;
CarroDAOImpl: http://paste-it.net/public/r176b96/

Links para o codigo fonte do projeto

paginas web: http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/web/web5.rar;
Classes Java: http://video.devmedia.com.br/discovirtual/210904/projeto SISMOT/classes/src5.rar

Desde já agradeço.











GOSTEI 0
Henrique Weissmann

Henrique Weissmann

07/09/2010

Oi Marcos,

aos pontos:

A respeito da primeira implementação.
Repare que há mais de uma implementação para o método load da interface org.hibernate.Session - http://docs.jboss.org/hibernate/stable/core/api/org/hibernate/Session.html

A que você está usando está passando dois parâmetros: Object e java.io.Serializable. Ele irá popular o objeto com os dados da sua classe. Este erro que você está reportando, está ocorrendo porque este método é um procedimento (void), e que portanto, realmente, não pode ser retornado. Sugiro que nesta situação, você use a outra implementação que te retorna um Object. Tal como no exemplo abaixo:

Session sessao = HIbernateUtil.getSession();
try { return (Carro) sessao.load(Carro.class, id); } catch (HibernateException ex) {
// faça o seu tratamento de erro aqui
}

Na segunda implementação, não vi problema algum.

Agora, continuando:
Sobre passagem de parâmetros para managed beans.
Inicialmente, o seu managed bean deve possuir um atributo acessível através de um get e um setter público e, como você está usando o JSF 1.2, este managed bean também deve estar presente no arquivo de configuração do faces.

Uma vez declarado o managed bean nas suas configurações, supondo que neste mesmo bean também exista o método que fará a consulta, tudo o que você precisa fazer é declarar a propriedade, tal como no exemplo jsp abaixo:





O método executar do seu managed bean terá acesso à propriedade naturalmente.

Sugestão de leitura: existe um livro maravilhoso sobre JSF chamado "Core JavaServer Faces" de David Geary e Cay Hortsman, agora na terceira edição que é a melhor fonte existente atualmente sobre este framework. Recomendo demais a sua leitura tanto pela simplicidade quanto pela concisão. É uma mão na roda para todos os que estão aprendendo.
Outra fonte muito bacana é o tutorial online da Oracle: "The Java EE Tutorial". Sugiro a seção "The web tier". É gratuito, e inferior ao livro acima citado, mas possui a vantagem do preço. Pode ser acessado neste endereço: http://download.oracle.com/javaee/6/tutorial/doc/
GOSTEI 0
Marcos Sousa

Marcos Sousa

07/09/2010

Henrique. Então não consigo aproveitar nenhum atributo de meus objetos já declarados no managedBean. No caso o managedBean e o QuartosAlugadosBean

public class QuartosAlugadosBean implements EntityBean {

    private Hospede hospede;

    //getters and setters omitidos

public String consultarPlaca() throws DAOException {
//        carros =  carroDAOImpl.buscarPlaca(carro);
        //Utilizando criteria do hibernate
        carro = carroDAOImpl.getEntidadeH(carro, carro.getPlaca());
   

        if (carro.equals(null)) {
            return "falhaPlaca";
        } else {
            return "sucessoPlaca";
        }

    }
}

//devo reescrever assim

public class QuartosAlugadosBean implements EntityBean {

    private Hospede hospede;
    private String consultaPlaca;

    //getters and setters omitidos

public String consultarPlaca() throws DAOException {
//        carros =  carroDAOImpl.buscarPlaca(carro);
        //Utilizando criteria do hibernate
        carro = carroDAOImpl.getEntidadeH(carro, consultaPlaca);
   

        if (carro.equals(null)) {
            return "falhaPlaca";
        } else {
            return "sucessoPlaca";
        }

    }
}

chamada na pagina de

             <tr>
                    <td><h:outputText value="Placa" /><h:inputText value="#{alugaQuartosBean.carro.placa}"/>
                      <h:commandButton value="Pesquisar placa" action="#{alugaQuartosBean.consultarPlaca}"/>
                   </td>
             </tr>

para esta nova chamada

             <tr>
                    <td><h:outputText value="Placa" /><h:inputText value="#{alugaQuartosBean.consultaPlaca}"/>
                      <h:commandButton value="Pesquisar placa" action="#{alugaQuartosBean.consultarPlaca}"/>
                   </td>
             </tr>

Desde já agradeço.

GOSTEI 0
Henrique Weissmann

Henrique Weissmann

07/09/2010

Marcos, esta sua dúvida é muito parecida com a do seu chamado anterior. Acredito que a tenha respondido neste outro chamado que você abriu, e que pode ser acessado neste link: https://www.devmedia.com.br/suporte/viewtopic.asp?id=388899
GOSTEI 0
Marcos Sousa

Marcos Sousa

07/09/2010

Correto. Eu refiz a pergunta comparando os dois exemplos, para que voce pudesse me afirmar o seguinte. Que eu não consigo aproveitar os objetos atribuídos e seus atributos no managedBean para os campos de pesquisa. Para isso tenho que criar novos atributos no meu managed bean que irão conversar direto com a view e carregar estes dados com String, o que e requerido pelo método load() do Hibernate.
GOSTEI 0
Henrique Weissmann

Henrique Weissmann

07/09/2010

Oi Marcos, não entendi os eu último post.
GOSTEI 0
Devmedia

Devmedia

07/09/2010

Marcos, para que possamos lhe ajudar, poderia explicar melhor os seus dois últimos posts, por favor.
GOSTEI 0
Marcos Sousa

Marcos Sousa

07/09/2010

Criei o seguinte atributo para o ManagedBean QuartosAlugadosBean
private String campoParaPesquisa;

//Omitido getters and setters

Tenho em meu form o seguinte campo para pesquisa:

 <h:form>
            <table>
                <tr>
                    <td><h:outputText value="Nome ou CPF" />
                        <h:inputText value="#{alugaQuartosBean.campoParaPesquisa}" />
                        <h:commandButton value="Pesquisar nome/CPF" action="#{alugaQuartosBean.consultarPorNomeCpf}"/>
                    </td>

                </tr>
            </table>
        </h:form>

Neste campo posso fazer pesquisas pelo nome ou cpf do hospede. Ele chama o metodo da QuartosAlugadosBean consultarPorNomeCpf que esta descrito abaixo:

 public String consultarPorNomeCpf() throws DAOException{
     
       hospede = hospedeDAOImpl.buscaPorParametro(hospede, campoParaPesquisa);

       if(hospede == null){
           statusHospede = false;
           return "falhaHospede";
      
          
       }else{
           statusHospede = true;
           return "sucessoHospede";
       }

   }

Tenho o seguinte método na DAO buscaPorParametro que realiza a consulta:

public Hospede buscaPorParametro(Hospede h, String nome) throws DAOException {
        Session session = HibernateUtil.getSession();
        try {
            Criteria busca = session.createCriteria(h.getClass());

            busca.add(Expression.eq("nome", nome));

            return (Hospede) busca.uniqueResult();
        } catch (org.hibernate.ObjectNotFoundException e) {
            return null;
        } catch (Exception ex) {
            throw new DAOException(ex);
        } finally {
        }

Neste exemplo eu tenho a linha
            busca.add(Expression.eq("nome", nome));
que é responsável por substituir a variavel nome ao atributo nome e realizar a query de consulta. Como faço para adicionar mais um valor para esta pesquisa.

Tentei fazer desta forma

busca.add(Expression.eq("nome", nome));
busca.add(Expression.eq("cpf", nome));

Mais não realizou a consulta.

Desde já agradeço.

fomAluguelQuarto.jsp: http://paste-it.net/public/mebf8da/
QuartosAlugadosBean: http://www.paste-it.net/public/n27c8fa/
HospedeDAOImpl: http://www.paste-it.net/public/ld3c7fd/

Desde já agradeço.
GOSTEI 0
Henrique Weissmann

Henrique Weissmann

07/09/2010

Oi Marcos, você deve proceder exatamente como mencionou, tal como está no seu próprio exemplo.

Se não retornou um valor, você deve se lembrar aqui do seguinte: ao incluir novas Expressions em uma Criteria, você está na realidade executando uma operação and maior.

Por exemplo: suponha que eu tenha a seguinte sequencia de operações.
criteria.add(Expression.eq("nome", "Henrique");
criteria.add(Expression.eq("cnpj", "08sadf0");

Isto será traduzido para SQL como algo do tipo
select (campos e from omitidos) where nome = 'Henrique' and 'cnpj' = '08sadf0'

Foi por esta razão que você não obteve nenhum registro do banco de dados. Ainda com relação à busca por nome, lembre-se que, dependendo do seu banco de dados, ele pode ser case sensitive, o que daria o mesmo resultado.

Agora: usando a Criteria do Hibernate, você pode incluir uma expressão do tipo "or" usando a classe Disjunction.

Dê uma olhada no seu Javadoc: http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/criterion/Disjunction.html

Também recomendo uma leitura neste link, que é a documentação do recurso Criteria do Hibernate: http://docs.jboss.org/hibernate/core/3.6/reference/pt-BR/html/querycriteria.html
GOSTEI 0
Marcos Sousa

Marcos Sousa

07/09/2010

Henrique fiz a seguinte alteração em meu método implementado na classe HibernateDAOImpl

public Hospede buscaPorParametro(Hospede h, String nome) throws DAOException {
        Session session = HibernateUtil.getSession();
        try {
            Criteria busca = session.createCriteria(h.getClass());
            busca.add(Expression.or
                    (Expression.eq("nome", nome),
                    Expression.eq("cpf",nome)));
            return (Hospede) busca.uniqueResult();
        } catch (org.hibernate.ObjectNotFoundException e) {
            return null;
        } catch (Exception ex) {
            throw new DAOException(ex);
        } finally {
        }

    }

Ele funcionou como esperado, mais quero resolver um problema relativo a limpar os campos para pesquisa. Ao pesquisar por placa ele me retorna o formulario com os dados do veiculo, quando eu realizo uma consulta pelo nome ou CPF ele mantém o formulario anterior e acrescenta os dados do formulário do hospede.

Consegui resolver este problema parciamente da seguinte forma.

Em minha classe QuartoAlugadosBean no metodo limparCampos() inseri o seguinte código

 public void limparCampos() {
        //limpa o formulario de carro
        if (statusCarro = false) {
            this.campoNomeCPF.equals(null);
            this.campoPlaca.equals(null);
            carro.setCor(null);
            carro.setId(null);
            carro.setPlaca(null);
            carro.setMarcaModelo(null);
            carro.setHospede(null);

        }
        //limpa o formulario de hospede
        if (statusHospede = false) {
            this.campoPlaca.equals(null);
            this.campoNomeCPF.equals(null);
            hospede.setId(null);
            hospede.setNome(null);
            hospede.setRg(null);
            hospede.setCpf(null);
        }

    }

Depois fiz a chamada deste metodo nos metodos que realizam a consulta dos dados

 public String consultarPorPlaca() throws DAOException {

        limparCampos();
       ...
}

 public String consultarPorNomeCPF() throws DAOException {

        limparCampos();
       ...
}

Ao realizar uma nova pesquisa, consigo ocultar o formulario não utilizado pela busca, mais o valor pesquisado anteriormente fica na caixa de input. Voce tem alguma sugestão para resolver este problema?

Desde já agradeço.

formAluguelQuarto.jsp: http://paste-it.net/public/j8995d0/
QuartosAlugadosBean: http://paste-it.net/public/zf37978/




GOSTEI 0
Henrique Weissmann

Henrique Weissmann

07/09/2010

Marcos, o problema é que seu managed bean deve estar com escopo de sessão. Neste caso, mude o escopo para requisição que deve resolver o problema.
GOSTEI 0
Marcos Sousa

Marcos Sousa

07/09/2010

Eu altereio o scopo para request e a aplicação funcionou da maneira esperada.

GOSTEI 0
Henrique Weissmann

Henrique Weissmann

07/09/2010

Marcos, posso então fechar este chamado?
GOSTEI 0
Marcos Sousa

Marcos Sousa

07/09/2010

Pode encerrar o chamado. Muito obrigado pelos esclarecimentos.

GOSTEI 0
POSTAR