Como resolver esse erro "EntityManager is closed" ?

Boa noite galera !! Estou com um problema na minha aplicação que não estou conseguindo resolver…Estou utilizando VRaptor mais Hibernate/JPA, e sempre quando vou gravar algo no Banco de Dados apenas o primeiro registro é gravado e a partir do segundo da erro: “EntityManager is closed”. Já pesquisei em vários fóruns sobre esse problema mas ainda não consegui resolver, alguém aí poderia me ajudar ?? Grato !! Segue abaixo mais informações

Exceção gerada

Classe Dao

a mensagem diz bastante: antes de voce invocar esse adiciona alguem acabou fechando o manager. provavelmente o outro metodo chamado tambem tem o manager.close, como esse que voce postou.

voce deve manter o manager aberto durante uma transacao ou sequencia de transacoes que considerar fazer sentido

1 curtida

Só que não tem nenhum outro método que chama “manager.close”, só o adiciona mesmo. Resolvi esse problema retirando o “manager.close” do adiciona, agora não sei se é recomendado fazer isso. Tem algum problema em deixar o “manager.close” sempre aberto ??

tenta isso:

manager.close();
factory.close();

Fazendo isso dar o seguinte erro: java.lang.OutOfMemoryError: PermGen space

esse problema é devido ao “estouro” da memória na JVM, mate todos seus processos java pelo Gerenciador de Tarefas e tente executar novamente

Ainda continua gerando a “EntityManager is closed”…Como j citado acima, a solução encontrada foi deixar ela sempre aberta…Só não sei se é correto fazer isso.

posta o código do metodo Arquivo.gravaBD

`public Boolean gravaBD(String diretorioArquivo) {
try {
FileInputStream stream;
// Lendo o arquivo, conforme o diretorio informado
stream = new FileInputStream(diretorioArquivo);
InputStreamReader reader = new InputStreamReader(stream);
BufferedReader br = new BufferedReader(reader);
// Variavel que armazena a linha a ser lida
String linha = br.readLine();
// Variavel que conta o numero de linhas lida até o momento
int contLoop = 0;
// Executa esse Loop enquanto existir linhas a serem lidas
while (linha != null) {
// Verifica se a linha é em branco
if (linha.equals("")) {
linha = br.readLine();
// pula o restante do codigo e lê uma nova linha
continue;
}
// Armazena os itens da linha, separadando-os por “,“
String[] itens = linha.split(”,”);
// Adicionando os itens a suas respectivas variaveis
String dataHora = itens[0];
// Convertendo de String para Date
Date dataUtil = formatadorYMDHMS.parse(dataHora);
java.sql.Timestamp dataSql = new java.sql.Timestamp(dataUtil.getTime());

            String temperatura = itens[1];
            String umidade = itens[2];
            String pressao = itens[3];
            System.out.println(dataSql + " " + temperatura + " " + umidade + " " + pressao);
            
            // Adicionando os dados formatados ao objeto
            Clima clima = new Clima();
            clima.setDataHora(dataSql);
            clima.setTemperatura(Float.parseFloat(temperatura));
            clima.setUmidade(Float.parseFloat(umidade));
            clima.setPressao(Float.parseFloat(pressao));
            
            // Adicionando dados ao banco
            resultado = dao.adiciona(clima);
            // Incrementa contador de loop
            contLoop++;
            // Mostra o progresso da gravação no monitor
            System.out.println("Gravado: " + contLoop);
            // Lê uma nova linha
            linha = br.readLine();
        }            
        
    } catch (FileNotFoundException ex) {
        Logger.getLogger(Arquivo.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException | ParseException ex) {
        Logger.getLogger(Arquivo.class.getName()).log(Level.SEVERE, null, ex);
    }
    return resultado;
}

`

Consegui resolver o problema…Apenas coloquei essa linha de codigo dentro do metodo adiciona:

EntityManager manager = factory.createEntityManager();

Dessa forma, toda vez que o adiciona é chamado o manager é instanciado e ao final do metodo ele é finalizado. Não sei se é boa prática, mas funcionou !! Obrigado pela ajuda galera !!

Voce poderia criar um interceptor que faz esse trabalho pra você já que usando vraptor, ou você pode usar um plugin do próprio vraptor e não fazer mais esse trabalho de manipular abertura/fechamento de transação.
http://www.vraptor.org/pt/docs/plugins/