NullPointerException ao usar o EntityManager num Filter de Servlet: JSF + JPA

2 respostas
MandicaBrito

Oi gente, estou fazendo um projeto na faculdade, usando JSF e JPA e para melhor organizar o código andei pesquisando formas de implementar a criação e controle de transações do meu EntityManager no filter da servlet do jsf, porém estou com um problema.
Aparentemente ele não consegue criar meu EM e por isso, ao chamar meus métodos genéricos do DAO, numa tela de pesquisa, por exemplo, ele acusa um nullpointer exception.

Seguem as classes:

Meu filtro:

public class EntityManagerFilter implements Filter{
	
	private EntityManagerFactory entityManagerFactory;

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain filterChain) throws IOException, ServletException {
		EntityManager entityManager = this.entityManagerFactory.createEntityManager();  
		request.setAttribute("entityManager", entityManager);  
        entityManager.getTransaction().begin();  
        filterChain.doFilter(request, response); 
        
        try{
        	entityManager.getTransaction().commit();
        }catch (Exception e) {
        	entityManager.getTransaction().rollback();
     	}finally{
			entityManager.close();  
	    }
        
        
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		entityManagerFactory = Persistence.createEntityManagerFactory("myJob360");
	}
	
	@Override
	public void destroy() {
		entityManagerFactory.close();
		
	}

	
	/**Getters e Setters*/
	public EntityManagerFactory getEntityManagerFactory() {
		return entityManagerFactory;
	}

	public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
		this.entityManagerFactory = entityManagerFactory;
	}
}
Meu DAO genérico:
public class GenericDAO<T> {
	
	private final EntityManager entityManager;
	private Class<T> classe;
	
	public GenericDAO(EntityManager entityManager, Class<T> classe){
		this.entityManager = entityManager;
		this.classe = classe;
	}
	
	public void inserir(T t){
		entityManager.persist(t);
	}
	
	public void alterar(T t){
		entityManager.merge(t);
	}
	
	public void excluir(T t){
		t = entityManager.merge(t);
		entityManager.remove(t);
	}
	
	public T consultar(int idClasse){
		return entityManager.find(classe, idClasse);
	}
	
	@SuppressWarnings("unchecked")
	public List<T> listarTodos(){
		StringBuilder sql = new StringBuilder();
		sql.append("select objeto from "+classe.getName()+" objeto order by objeto.id desc");
		
		Query consulta = entityManager.createQuery(sql.toString()); // Acusa a exceção nessa linha
		
		return consulta.getResultList();
	}
	
	public final void iniciaEntityManager(){
		entityManager.getTransaction().begin();
	}
	
	public final void encerraEntityManager(){
		entityManager.getTransaction().commit();
	}
	
}
Minha classe de controle, que chama esse DAO genérico:
@ManagedBean
public class CategoriaControle {

	@ManagedProperty(value="#{entityManager}")
	private EntityManager entityManager;
	private GenericDAO<Categoria> dao = new GenericDAO<Categoria>(entityManager, Categoria.class);

	private List<Categoria> categorias = new ArrayList<Categoria>(dao.listarTodos());
	private List<Categoria> categories;

	public void inserir(Categoria categoria) {
		dao.inserir(categoria);
	}

	public void alterar(Categoria categoria) {
		dao.alterar(categoria);
	}

	public void excluir(Categoria categoria) {
		dao.excluir(categoria);
	}

	public List<Categoria> listar() {
		categorias = new ArrayList<Categoria>(dao.listarTodos());
		return categorias;
	}
public EntityManager getEntityManager() {
		return entityManager;
	}

	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

	public List<Categoria> getCategorias() {
		return categorias;
	}

	public void setCategorias(List<Categoria> categorias) {
		this.categorias = categorias;
	}

	public void setCategories(List<Categoria> categories) {
		this.categories = categories;
	}

	public GenericDAO<Categoria> getDao() {
		return dao;
	}

	public void setDao(GenericDAO<Categoria> dao) {
		this.dao = dao;
	}

E finalmente, o bean que trabalha com o xhtml:

@SessionScoped
@ManagedBean
public class CategoriaBean {
	
	private Categoria categoria = new Categoria();
	private String nome;
	
	public void salvar() {
		CategoriaControle categoriaControle = new CategoriaControle();
		categoriaControle.inserir(categoria);
		categoria = new Categoria();
		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Categoria: ", "Registro cadastrado com sucesso!"));  
		
	}

	public List<Categoria> listar() {
		CategoriaControle categoriaControle = new CategoriaControle();
		return categoriaControle.listar();
	}

	public void alterar() {
		CategoriaControle categoriaControle = new CategoriaControle();
		categoriaControle.alterar(categoria);
		categoria = new Categoria();
		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Categoria: ", "Registro alterado com sucesso!"));
	
	}

	public void excluir() {
		CategoriaControle categoriaControle = new CategoriaControle();
		categoriaControle.excluir(categoria);
		categoria = new Categoria();
		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Categoria: ", "Registro excluido com sucesso!"));
	
	}


	
	
	/**Getters e Setters */
	public Categoria getCategoria() {
		return categoria;
	}

	public void setCategoria(Categoria categoria) {
		this.categoria = categoria;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}


}
O web.xml está desse jeito:
<?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_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>myJob360</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>*.jsf</url-pattern>
	</servlet-mapping>

	<context-param>
		<param-name>primefaces.THEME</param-name>
		<param-value>bluesky</param-value>
	</context-param>

	<filter>
		<filter-name>EntityManagerFilter</filter-name>
		<filter-class>filtro.EntityManagerFilter</filter-class>
	</filter>
	
	<filter-mapping>
		<filter-name>EntityManagerFilter</filter-name>
		<servlet-name>Faces Servlet</servlet-name>
	</filter-mapping>
</web-app>

E a tela que estou tentando abrir é essa:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:p="http://primefaces.org/ui"
	xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>
	<title>Categoria</title>
	<link rel="stylesheet" type="text/css"
		href="#{facesContext.externalContext.requestContextPath}/css/style.css" />
</h:head>

<h:body>
	<div id="cabecalho" />
	<f:view contentType="text/html" />
	<h:form id="formPesquisarCategoria">
		<div id="barra_menu" />

		<p:messages id="messages" showDetail="true" autoUpdate="true"
			closable="true" />

		<h:panelGrid columns="1">

			<h:outputLabel value="Nome" for="nome" />
			<p:inputText value="#{categoriaBean.nome}" id="nome"
				size="60" />
			<br />
			<p:commandButton value="Pesquisar" action="#{categoriaBean.listar}"
				ajax="false">
				<f:param name="nomeCategoria" value="#{categoriaBean.nome}" />
			</p:commandButton>


		</h:panelGrid>
		<br />

		<h:panelGrid columns="1">

			<h:outputLabel value="Resultados Encontrados" />
			<p:separator id="separatorTable" style="width:450px" />
		</h:panelGrid>

		<br />

		<div align="center">
                      
                    // Nesse dataTable ele chama uma lista, que é preenchida usando o DAO, mas como  o EM não é criado, ele mostra logo a exceção no navegador
			<p:dataTable value="#{categoriaControle.categorias}" var="cat" 
				rendered="#{categoriaControle.categorias != null}">

				<p:column headerText="Nome">
					<p:commandLink
						action="#{redirecionarUtil.redirecionarCategoriaConsultar}">
						<h:outputText value="#{cat.nome}" />
						<f:setPropertyActionListener target="#{categoriaBean.categoria}"
							value="#{cat}" />
						<f:param name="objCategoria" value="#{cat}" />
					</p:commandLink>
				</p:column>


			</p:dataTable>

		</div>
		<br />

		<p:commandButton value="Cadastrar"
			actionListener="#{redirecionarUtil.redirecionarCategoriaCadastrar}"
			ajax="false" />


	</h:form>
</h:body>
</html>

Vi exemplos semelhantes aqui mesmo no fórum, mas as soluções propostas pelos colegas não conseguiram me ajudar.
Agradeço que puder dar uma olhadinha ^^

2 Respostas

Hebert_Coelho

Seu null pointer não é pq você não passou nenhum valor para o entity manager factory?

Outra coisa, pra que você está colocando o entity manager dentro do request? O.o

MandicaBrito

Bem, estava seguindo exemplos que vi, por isso o entityManager está no request. Ele deveria estar em outro lugar?
Já verifiquei e o entityManagerFactory está preenchido sim, quando ele tenta executar a linha filterChain.doFilter(request, response); é que para de funcionar, já reparei isso também.

Criado 18 de novembro de 2012
Ultima resposta 18 de nov. de 2012
Respostas 2
Participantes 2