JPA : EntityManager is closed

Olá pessoal, estou tentando adicionar um usuário via VRaptor na minha aplicação mas na hora de enviar os dados é lançada uma "IllegalStateException:EntityManager is closed", acusando minha classe UsuarioLogic na linha:

public void adiciona (Usuario usuario) {
		this.daoFactory.beginTransaction(); // ESTA LINHA<<<<<<<<<<<<<<<
		this.daoFactory.getUsuarioDao().adiciona(usuario);
		this.daoFactory.commit();
} 

…que por consequencia minha DaoFactory:

public void beginTransaction () {
		tx = this.manager.getTransaction();
		tx.begin(); // NESTA LINHA<<<<<<<<<<<<<<<
}

Estou usando um DaoInterceptor para fazer a injeção do DaoFactory nas classes de lógica:

public class DaoInterceptor implements Interceptor {
	
	private final DaoFactory factory = new DaoFactory();


	public void intercept(LogicFlow flow) throws LogicException, ViewException {
	
		flow.execute();
		if (factory.hasTransaction()) {
			factory.rollback();
		}
		factory.close();		
		
	}
	
	@Out(key="br.com.leandro.orcamento.dao.DaoFactory")
	public DaoFactory getFactory() {
		return factory;
	}
	
	

}

Não sei se fui claro o bastante, mas quem puder me ajudar com este problema eu agradeço.
[]´s

Onde você está injetando o EntityManager? Pois o que está acontecendo é que você está tentando abrir uma transação a partir de um EntityManager que já foi fechado.

Valeu Guilherme, arrumei este problema, pois na minha classe JpaUtil, meu EntityManager era uma variável estática, e a cada requisição, ele estava sendo fechado pelo Interceptor.

Agora, todos que pedem um EntityMAnager, recebe um novo, e não um da classe:

public class JpaUtil {
	

	private static EntityManagerFactory factory;
	
	static {
		factory = Persistence.createEntityManagerFactory("leandro");		

	}
	
	public static EntityManager getManager () {
		
		return factory.createEntityManager();
		
	}
}

Obrigado, []´s

Aproveitando o gancho do tópico… tbm estou com a mesma situação…

Estou com o seguinte DAO Genérico…

package com.wordpress.aohana.gecon.geral.base;

import com.wordpress.aohana.gecon.geral.interfaces.IBaseDAO;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**
 * Classe Abstrata que implementa os metodos de persistencia da aplicaçao,
 * recebendo a Entidade necessaria atraves de um generico <T>.
 *
 * @author Adriano Ohana
 * @since Abril 15, 2009
 */
public abstract class BaseDAO<T> implements IBaseDAO<T> {

    private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("GECONPU");
    private static EntityManager em = emf.createEntityManager();

    public void persist(T entidade) {
        em.getTransaction().begin();
        try {
            em.persist(entidade);
            em.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }

    public List<T> findByAll(String query) {
        try {
            return em.createNamedQuery(query).getResultList();
        } catch(Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public List<T> findByName(String query, String nome) {
        try {
            return em.createNamedQuery(query).setParameter("nome", "%" + nome.toUpperCase() + "%").getResultList();
        } catch(Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void fecharConexao() {
        em.close();
    }
}

Esse último método fecharConexao() eu acabei de implementar pra fechar a conexao somente quando o Sistema sai… porém não é bem isso que eu queria… queria abrir e fechar a conexao sempre que fosse executar alguma intrução de persistencia na base… Teria que criar esse EntityManager dentro dos meus métodos e abrir e fechar a cada INSERT, UPDATE e DELETE ???

Valew Galera :wink:

Uma sugestão:
O ideal seria vc fazer um método separado para abrir a conexão, outro para commit, outro para close, e assim por diante, todos dentro dessa Dao.
A idéia é que, a classe que instanciar esse Dao, ela faça a abertura da conexão, a persistência, e tbm feche a conexão.

Algo parecido com isso:

dao.beginTransaction();
dao.persist(obj);
dao.commit;

Dependendo do controlador da sua aplicação, algum interceptor, ou filtro dessa logica, que faça o rollback e o close.

Espero ter ajudado.
[]´s

Para o leandronsp

Na sua JpaUtil, ao invés de retornar sempre um novo, usa ThreadLocal e usa um único entity manager por thread, é mais comum fazerem dessa forma.

1 curtida