JSF não funciona com JPA

oi pessoal… estou com problema na execução de uma página JSF com JPA… o q ocorre é q quando eu executo o código jpa como uma stand alone app td funciona mas quando eu executo do jsf dá erro…

espero q alguém saiba o q pd tá ocorrendo pq sinceramente eu não faço idéia…

lá vai…

eu tenho a classe JpaUtil q me retorna o entitymanager

public class JpaUtil {

	private static JpaUtil me;
	private EntityManagerFactory factory;
	
	private JpaUtil () {
		factory = Persistence.createEntityManagerFactory("pu1");
	}
	
	public static JpaUtil getInstance() {
		if (me == null) {
			me = new JpaUtil();
		}
		return me;
	}
	
	public EntityManager createEntityManager() {
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		return em;
	}
}

daí eu tenho a classe FirstJsfandjpa q é meu managedBean

public class FirstJsfandjpa {

	private List<People> people;
	
	public FirstJsfandjpa() {
		EntityManager em = (EntityManager) JpaUtil.getInstance().createEntityManager();
		people = em.createQuery("select pl from People pl").getResultList();
		em.getTransaction().commit();
		em.close();
	}

	public List<People> getPeople() {
		return people;
	}

	public void setPeople(List<People> people) {
		this.people = people;
	}
}

dái eu tenho a classe Execute q me lista todas as pessoas… quando eu rodo esse código td funciona perfeitamente

public class Execute {

	List<People> people = new FirstJsfandjpa().getPeople();
	
	public static void main(String[] args) {
		
		List<People> people = new FirstJsfandjpa().getPeople();
		
		for (People pl: people) {
			System.out.println(pl.getName());
		}
	}
}

mas se eu rodar da página JSF dá erro.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="f"  uri="http://java.sun.com/jsf/core"%>
<%@ taglib prefix="h"  uri="http://java.sun.com/jsf/html"%>
<!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>JSF and JPA example</title>
</head>
<body>
<f:view>
	<h1><h:outputText value="People listed" /></h1>
	<h:dataTable var="people" value="#{FirstJsfandjpa.people}">
		<h:column>
			<f:facet name="header">
				<h:outputText value="Name" />
			</f:facet>
			<h:outputText value="#{people.name}" />
		</h:column>
	</h:dataTable>
</f:view>
</body>
</html>

quando eu acesso esta página dá erro e parece q o erro é na classe JpaUtil… mas se eu consigo rodar o programa da classe Execute então JpaUtil deve tá certinho e eu não sei pq esse erro ocorre na página JSF:

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: Servlet execution threw an exception

root cause

java.lang.NoClassDefFoundError: javax/persistence/Persistence
br.com.devmedia.entity.JpaUtil.(JpaUtil.java:13)
br.com.devmedia.entity.JpaUtil.getInstance(JpaUtil.java:18)
br.com.devmedia.faces.FirstJsfandjpa.(FirstJsfandjpa.java:16)
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
java.lang.reflect.Constructor.newInstance(Constructor.java:513)
java.lang.Class.newInstance0(Class.java:355)
java.lang.Class.newInstance(Class.java:308)
com.sun.faces.mgbean.BeanBuilder.newBeanInstance(BeanBuilder.java:185)
com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:105)
com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:368)
com.sun.faces.mgbean.BeanManager.create(BeanManager.java:222)
com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:86)
javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54)
com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:61)
org.apache.el.parser.AstValue.getValue(AstValue.java:107)
org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
org.apache.jasper.el.JspValueExpression.getValue(JspValueExpression.java:101)
javax.faces.component.UIData.getValue(UIData.java:614)
javax.faces.component.UIData.getDataModel(UIData.java:1129)
javax.faces.component.UIData.setRowIndex(UIData.java:451)
com.sun.faces.renderkit.html_basic.TableRenderer.encodeBegin(TableRenderer.java:77)
javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:813)
javax.faces.component.UIData.encodeBegin(UIData.java:967)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:928)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:933)
com.sun.faces.application.ViewHandlerImpl.doRenderView(ViewHandlerImpl.java:266)
com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:197)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)

note The full stack trace of the root cause is available in the Apache Tomcat/6.0.20 logs.

Bom dia Fabiano,

Você está com os jar´s no seu classpath quando roda a aplicação JSF?

Me parece que o erro está na linha

factory = Persistence.createEntityManagerFactory("pu1"); não está localizando a classe Persistence.
T+

Bom dia Gilson… bom… eu to usando o eclipse… acredito q todos os jars estejam corretos pq eu criei uma página jsf de teste e funciona e os jars do jpa devem tá ok pq a classe execute tbém funciona…

mas pd ser q esteja faltando algum outro jar q eu desconheça…

jars do JSF da applicação:

commons-beanutils-1.8.0.jar
commons-collections-3.2.1.jar
commons-digester-2.0.jar
commons-logging-1.1.1.jar
jsf-api.jar
jsf-impl.jar
jstl.jar
standard.jar

O problema que estava acontecendo comigo era porque o container -Tomcat, não consegui instanciar o EntityManager.

Tive um problema desses e resolvi controlando as Transações com JOTM.

Att…

Eu acho q pelo fato do tomcat ser um web container deve ter uma configuração específica pra ele funcionar com JPA…
. eu vou tentar rodar a app com Glassfish… quem sabe funciona

Quanto tive meu problema, tambem o fiz, este teste no Glashfish e funcionou pois ele controla as transações.

Outra solução seria voce colocar o Spring como gerenciado de trasações.

Att…

eu to levando uma surra pra instalar o glassfish no eclipse galileo… parece q essa versão do eclipse tá com bug e o site de dowload q o pessoal fala não funciona… se alguém já teve esse problema e conseguiu resolver posta aí…

fallow!

para roda no tomcat, vc tem que adicionar o jar “ejb3-persistence.jar”. O glassfish não tem uma interação legal com o eclipse mesmo, portando eu recomendo usar netbeans ou usar o app JBoss que é mais tranquilo que usar com o eclipse.

No mais, se realmente vc quizer glassfish e eclipse, baixe a ide “Glassfish bundle eclipse”

outra coisa: qual framework vc está usando para persistencia? EclipseLink, Hibernate, TopLink?

se vc estiver usando o TopLink, tem que adicionar o TopLink Essentials JPA e o TopLink Agent;
se for Hibernate, tem que adicionar o Hibernate EntityManager;
se for o EclipseLink, tem que adicionar o EclipseLink

mostra o seu persistence.xml para agente poder ver certinho o que vc está usando

eu to usando o hibernate, esse arquivo ejb3-persistence.jar já tá no classpath… eu acredito q td esteja certinho pois td funciona quando eu executo como standalone app… o problema ocorre quando eu executo no tomcat…

das duas uma… ou o tomcat não tá enxergando o arquivo de persistência ou o tomcat não funciona com JPA…

… mas acho q vou seguir seu conselho e tentar rodar com JBOSS…

valeu!

A respeito de suas perguntas.

  1. O Tomcat pode até enxergar a persistence,outra coisa é ele poder instanciar,gerenciar e ‘controlar’ o EntityManager e suas transações.

  2. Ele funciona com JPA, tenta fazer apenas uma alteração no seu persisitence, colocanco um gerenciador de transação, como suregido JOTM.

Seu persistence ficaria mais ou menos assim:

<persistence version="1.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="jsf" transaction-type="JTA">
	<provider>org.hibernate.ejb.HibernatePersistence</provider>
	<jta-data-source>java:comp/env/jdbc/jsf</jta-data-source>//Nome da transação JTA e configurada com 
	<class>beans.TesteJSF</class>
	<exclude-unlisted-classes>true</exclude-unlisted-classes>
	<properties>
		<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
		<property name="hibernate.hbm2ddl.auto" value="update"/>
		<property name="jta.UserTransaction" value="java:comp/UserTransaction"/>
		<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/>
		<property name="hibernate.transaction.manager_lookup_class"value="org.hibernate.transaction.JOTMTransactionManagerLookup"/>
	</properties>
</persistence-unit>
</persistence>

E seu arquivo context.xml ficaria assim:

<Context antiJARLocking="true" path="/JSF2"> //Contexto da Aplicação
	<Resource name="jdbc/jsf" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" 		username="usuario" password="senha" driverClassName="drive de seu banco" url="url do seu banco"/>
	<Transaction name="UserTransaction" auth="Application" type="javax.transaction.UserTransaction" 		factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60"/>
</Context>

Ai é só colocar os arquivos .jar no path de sua aplicação e correr pro abraço…

blz… eu preciso de algum outro .jar além dos q eu uso no hibernate pra usar JOTM?

Baixa este arquivo que contem os jar’s necessario…

http://forge.ow2.org/project/download.php?group_id=19&file_id=12408

Ou visita a pagina e escolhe a versão pra ser utilizada…

http://forge.ow2.org/project/showfiles.php?group_id=19