Problema com JSF 1.2 + Hibernate. [Resolvido]

Olá a todos,

Estou estudando J2EE pelo livro “JSP, Servlets, Javaserver Faces, Hibernate, EJB 3 Persistence e Ajax” do Edson Gonçalves, estava conseguindo enteder tudo e seguir todos os exemplos até chegar a parte em que temos que usar o Hibernate para fazer a persistência dos dados.

É um exemplo bem simples, de uma “livraria”, um site que cadastra livros, exclui, e mostra os mesmos em uma tabela, usando JSF 1.2.

O container utilizado é o Tomcat 6.0

No exemplo, a comunicação com o banco a priori é feita utilizando JDBC puro, com os métodos DAO e uma Interface que armazena os métodos utlizados para o acesso ao banco. Sem o hibernate, o exemplo funciona perfeitamente, mas quando tento fazer a comunicação com o banco utilizando o Hibernate, ao tentar listar todos os livros o seguinte erro acontece: [color=red]“javax.faces.FacesException: org.apache.jasper.el.JspELException: /mostrarLivros.jsp(16,2) ‘#{livrosView.todos}’ Error reading ‘todos’ on type br.com.teste.controller.LivrosControllerHibernate”[/color] (O stack completo do erro está no final do post)

Pelo que entendi do erro, o problema é que não existe o método/atributo ‘todos’ na minha variável livrosView.

Mas o estranho é que ele existe, tanto que quando eu rodo a aplicação com o JDBC sem o Hibernate, tudo funciona.

Já procurei em fórum, listas, e no próprio site do autor do livro, pedi ajuda a amigos, mas não consegui resolver isso, se alguem puder me ajudar a entender o que está acontecendo, eu ficaria muito agradecido.

Quando quero mudar o acesso a banco para JDBC apenas altero o managed-bean LivrosView para pegar a classe de controle que chama os métodos DAO sem o Hibernate, e tudo funciona. Testei tambem se minha implementação do Hibernate está correta, fiz uma classe teste que pega os livros do banco e mostra com System.out.println, funcionou perfeitamente, isso tudo só me leva a crer que erro seja relacionado a integração do JSF 1.2 com o Hibernate.

Aqui estão minhas classes (O código está resumido para o post não ficar muito extenso, caso precisem de mais alguma informação, eu edito)

Arquivo faces-config.xml

<managed-bean>
    <managed-bean-name>livrosView</managed-bean-name>
    <managed-bean-class>br.com.teste.controller.LivrosControllerHibernate</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>ProjetoJSF</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>
  <context-param>
    <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
  </context-param>
  <context-param>
    <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
    <param-value>resources.application</param-value>
  </context-param>
  <listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
  </listener>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.faces</url-pattern>
  </servlet-mapping>
</web-app>

LivrosControllerHibernate

package br.com.teste.controller;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.validator.ValidatorException;

import br.com.teste.dao.InterfaceLivrosHibernateDAO;
import br.com.teste.dao.LivroHibernateDAO;
import br.com.teste.entity.Livro;

public class LivrosControllerHibernate {

private Livro livro;
	
	private DataModel model;
	
	public String novoLivro(){
		this.livro = new Livro();
		return "novo";
	}
	
	public Livro getLivro(){
		return livro;
	}
	
	public void setLivro(Livro livro){
		this.livro=livro;
	}
	
	public DataModel getTodos(){
		InterfaceLivrosHibernateDAO idao = new LivroHibernateDAO();
		model= new ListDataModel(idao.todosLivros());
		return model;
	}
	
	public Livro getLivroFromEditOrDelete(){
		Livro livro = (Livro) model.getRowData();
		return livro;
	}
	
	public String editar(){
		Livro livro = getLivroFromEditOrDelete();
		setLivro(livro);
		return "editar";
	}
	
	public String update(){
		InterfaceLivrosHibernateDAO idao = new LivroHibernateDAO();
		idao.atualizar(livro);
		return "sucesso_atu";
	}
	
	public String excluir(){
		InterfaceLivrosHibernateDAO idao = new LivroHibernateDAO();
		Livro livro = getLivroFromEditOrDelete();
		idao.excluir(livro);
		return "sucesso_exc";
	}
	
	public String create(){
		InterfaceLivrosHibernateDAO idao = new LivroHibernateDAO();
		idao.salvar(livro);
		return "sucesso_ins";
	}
	
	public void validaISBN(FacesContext context, 
			UIComponent component, Object objeto) throws ValidatorException{
		
		String isbnDigitado = (String)objeto;
		
		Pattern p = Pattern.compile("\\d{1,2}-\\d{3,5}-\\d{3,4}-[0-9xX]{1}");
		Matcher m = p.matcher(isbnDigitado);
		
		boolean matchFound = m.matches();
		
		if(!matchFound){
			((UIInput)component).setValid(false);
			FacesMessage message = new FacesMessage("ISBN Inválido");
			context.addMessage(component.getClientId(context),message);
		}
	}
	
}

InterfaceLivrosHibernateDAO

package br.com.teste.dao;

import java.util.List;

import br.com.teste.entity.Livro;

public interface InterfaceLivrosHibernateDAO {

	public abstract void atualizar(Livro livro);
	public abstract void excluir(Livro livro);
	public abstract void salvar(Livro livro);
	public abstract List<Livro> todosLivros();
	
}

LivroHibernateDAO

package br.com.teste.dao;

import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import br.com.teste.entity.Livro;
import br.com.teste.util.ConnectLivrariaFactoryHibernate;

public class LivroHibernateDAO implements InterfaceLivrosHibernateDAO{

	private Session session;
	
	public void salvar(Livro livro){
		session=ConnectLivrariaFactoryHibernate.getInstance();
		Transaction tx = null;
		
		try{
			tx=session.beginTransaction();
			session.save(livro);
			tx.commit();
		}catch(HibernateException e){
			e.printStackTrace();
			tx.rollback();
		}finally{
			session.close();
		}
	}
	
	public void excluir(Livro livro){
		session=ConnectLivrariaFactoryHibernate.getInstance();
		Transaction tx = null;
		
		try{
			tx=session.beginTransaction();
			session.delete(livro);
			tx.commit();
		}catch(HibernateException e){
			e.printStackTrace();
			tx.rollback();
		}finally{
			session.close();
		}
	}
	
	public void atualizar(Livro livro){
		session=ConnectLivrariaFactoryHibernate.getInstance();
		Transaction tx = null;
		
		try{
			tx=session.beginTransaction();
			session.update(livro);
			tx.commit();
		}catch(HibernateException e){
			e.printStackTrace();
			tx.rollback();
		}finally{
			session.close();
		}
	}
	
	public List<Livro> todosLivros(){
		session=ConnectLivrariaFactoryHibernate.getInstance();
		System.out.print("Passei aqui!!!");
		@SuppressWarnings("unchecked")
		List<Livro> list = session.createQuery("from Livro").list();
		for (Livro livro : list) {
			System.out.println(livro.getTitulo());
		}
		return list;
	}
	
}

ConnectionLivrariaFactoryHibernate

package br.com.teste.util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ConnectLivrariaFactoryHibernate {

	private static final SessionFactory SESSION_FACTORY;
	private static final ThreadLocal<Session> THREAD_LOCAL =
		new ThreadLocal<Session>();
	
	static{
		try{
			SESSION_FACTORY = new Configuration()
			.configure("hibernate.cfg.xml").buildSessionFactory();
		}catch(Throwable t){
			t.printStackTrace();
			throw new ExceptionInInitializerError(t);
		}
	}
	public static Session getInstance(){
		Session session = (Session)THREAD_LOCAL.get();
		session = SESSION_FACTORY.openSession();
		THREAD_LOCAL.set(session);
		return session;
	}
}

mostrarLivros.jsp (A jsp que é chamada quando eu clico no link de mostrar livros)

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Mostrar Livros</title>
<link rel="stylesheet" href="recursos/css/estilo_padrao.css" media="all">
</head>
<body>
<f:view>
	<h:messages/>
	<h:form>
		<h:dataTable value="#{livrosView.todos}" var="item" border="1" 
		cellpadding="2" cellspacing="0" styleClass="tabela" 
		headerClass="cabecalho" rowClasses="linha_a,linha_b">
		<f:facet name="header">
			<h:outputText value="Mostrar Livros"/>
		</f:facet>
			<h:column>
				<f:facet name="header">
					<h:outputText value="ISBN"/>
				</f:facet>
				<h:commandLink action="#{livrosView.editar}" value="#{item.isbn}"/>
			</h:column>
			<h:column>
				<f:facet name="header">
					<h:outputText value="Titulo"/>
				</f:facet>
				<h:outputText value="#{item.titulo}"/>
			</h:column>
			<h:column>
				<f:facet name="header">
				<h:outputText value="Publicado em"/>
				</f:facet>
				<h:outputText value="#{item.publicacao}" converter="converteAnoMySQL"/>
			</h:column>
			<h:column>
				<f:facet name="header">
					<h:outputText value="Excluir Livro"/>
				</f:facet>
				<h:commandLink action="#{livrosView.excluir}" value="Excluir"/>
			</h:column>
		</h:dataTable>
		<h:commandLink action="#{livrosView.novoLivro}" value="Cadastrar novo livro"/>
	</h:form>
</f:view>
</body>
</html>

hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<session-factory>
		<property name="hibernate.connection.driver_class">
			org.gjt.mm.mysql.Driver
		</property>
		<property name="hibernate.connection.url">
			jdbc:mysql://localhost/livraria
		</property>
		<property name="hibernate.connection.username">
			root
		</property>
		<property name="hibernate.connection.password">
			root
		</property>
		<property name="hibernate.dialect">
			org.hibernate.dialect.MySQLDialect
		</property>
		<mapping resource="livro.hbm.xml"/>
	</session-factory>
</hibernate-configuration>

livro.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"//Hibernate/Hibernate Mapping 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
	<class name="br.com.teste.entity.Livro" table="livros">
		<id name="isbn" column="isbn" type="string">
			<generator class="assigned" />
		</id>
		<property name="titulo" type="string" />
		<property name="edicao" column="edicao_num" type="integer" />
		<property name="publicacao" column="ano_publicacao" type="string" />
		<property name="descricao" type="string" />
	</class>
</hibernate-mapping>

O stack completo do erro:

AVISO: executePhase(RENDER_RESPONSE 6,com.sun.faces.context.FacesContextImpl@6c1a82) threw exception
javax.faces.FacesException: org.apache.jasper.el.JspELException: /mostrarLivros.jsp(16,2) ‘#{livrosView.todos}’ Error reading ‘todos’ on type br.com.teste.controller.LivrosControllerHibernate
at javax.faces.component.UIData.getValue(UIData.java:585)
at javax.faces.component.UIData.getDataModel(UIData.java:1063)
at javax.faces.component.UIData.setRowIndex(UIData.java:417)
at com.sun.faces.renderkit.html_basic.TableRenderer.encodeBegin(TableRenderer.java:85)
at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:785)
at javax.faces.component.UIData.encodeBegin(UIData.java:879)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:884)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:137)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:809)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:886)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:892)
at com.sun.faces.application.ViewHandlerImpl.doRenderView(ViewHandlerImpl.java:244)
at com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:175)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:106)
at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:144)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:245)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Unknown Source)
Caused by: org.apache.jasper.el.JspELException: /mostrarLivros.jsp(16,2) ‘#{livrosView.todos}’ Error reading ‘todos’ on type br.com.teste.controller.LivrosControllerHibernate
at org.apache.jasper.el.JspValueExpression.getValue(JspValueExpression.java:107)
at javax.faces.component.UIData.getValue(UIData.java:582)
… 28 more
Caused by: java.lang.NoClassDefFoundError: org/hibernate/HibernateException
at br.com.teste.controller.LivrosControllerHibernate.getTodos(LivrosControllerHibernate.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:62)
at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54)
at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:64)
at org.apache.el.parser.AstValue.getValue(AstValue.java:123)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
at org.apache.jasper.el.JspValueExpression.getValue(JspValueExpression.java:101)
… 29 more
Caused by: java.lang.ClassNotFoundException: org.hibernate.HibernateException
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1645)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1491)
… 40 more
10/01/2011 15:35:45 org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() for servlet Faces Servlet threw exception
java.lang.ClassNotFoundException: org.hibernate.HibernateException
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1645)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1491)
at br.com.teste.controller.LivrosControllerHibernate.getTodos(LivrosControllerHibernate.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:62)
at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54)
at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:64)
at org.apache.el.parser.AstValue.getValue(AstValue.java:123)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
at org.apache.jasper.el.JspValueExpression.getValue(JspValueExpression.java:101)
at javax.faces.component.UIData.getValue(UIData.java:582)
at javax.faces.component.UIData.getDataModel(UIData.java:1063)
at javax.faces.component.UIData.setRowIndex(UIData.java:417)
at com.sun.faces.renderkit.html_basic.TableRenderer.encodeBegin(TableRenderer.java:85)
at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:785)
at javax.faces.component.UIData.encodeBegin(UIData.java:879)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:884)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:137)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:809)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:886)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:892)
at com.sun.faces.application.ViewHandlerImpl.doRenderView(ViewHandlerImpl.java:244)
at com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:175)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:106)
at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:144)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:245)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Unknown Source)

Coloca o stack completo.

Coloquei o stack completo do erro no final do post.

Ó:

Caused by: java.lang.NoClassDefFoundError: org/hibernate/HibernateException 

Tá faltando jar ai

Você saberia dizer qual lib ta faltando? Vou deixar aqui a lista das que estão no meu projeto.

As libs do JSF e do Tomcat, as do JSTL, e do hibernate, as seguintes:

antlr-2.7.6.jar
asm.jar
asm-attrs.jar
dom4j-1.6.1.jar
hibernate3.jar
javassist-3.9.0.GA.jar
jta-1.1.jar
c3p0-0.9.1.jar
cglib-2.2.jar
slf4j-api-1.6.1.jar

Dentro da lib hibernate3.jar que está no classpath do meu projeto, tem org/hibernate/HibernateException.class

Então não sei porque esse erro está acontecendo. Alguem pode ajudar?

[quote=raf4ever]Ó:

Caused by: java.lang.NoClassDefFoundError: org/hibernate/HibernateException 

Tá faltando jar ai[/quote]

raf4ever,

Estava faltando a lib ehcache-1.2.jar

Muito obrigado pela a ajuda!

Só pra constar que no livro não fala sobre a dependência desse jar.

Vou deixar aqui as Libs que ficaram no classpath do projeto, caso alguem precise:

Libs para o funcionamento do Hibernate (sem annotations)

antlr-2.7.6.jar
asm.jar
asm-attrs.jar
dom4j-1.6.1.jar
hibernate3.jar
jta.jar
c3p0-0.9.0.jar
cglib-2.1.3.jar
ehcache-1.2.jar
commons-collections-2.1.1.jar
commons-logging-1.0.4.jar

Libs para o funcionamento do JSF 1.2

commons-beanutils-1.8.3.jar
commons-collections-3.2.1.jar
commons-digester-2.1.jar
commons-logging-1.1.1.jar
jsf-api.jar
jsf-impl.jar