Fórum problema com projeto em JSF 1.2 #385805
07/09/2010
0
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
Curtir tópico
+ 0Posts
07/09/2010
Henrique Weissmann
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
08/09/2010
Marcos Sousa
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
09/09/2010
Henrique Weissmann
Gostei + 0
10/09/2010
Marcos Sousa
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
12/09/2010
Henrique Weissmann
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
14/09/2010
Marcos Sousa
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
14/09/2010
Henrique Weissmann
Gostei + 0
16/09/2010
Marcos Sousa
Gostei + 0
27/09/2010
Henrique Weissmann
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
29/09/2010
Marcos Sousa
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
29/09/2010
Henrique Weissmann
Gostei + 0
02/10/2010
Marcos Sousa
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
04/10/2010
Henrique Weissmann
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
06/10/2010
Marcos Sousa
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
13/10/2010
Henrique Weissmann
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
Clique aqui para fazer login e interagir na Comunidade :)