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();
}
}
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 ???
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.