Persistindo com JPA - Hibernate - Abrir uma vez só e persistir 1000 objetos - Resolvido

11 respostas
C

Bom dia pessoal,
estou fazendo um comparativo entre tecnologias e uma delas é a persistencia em um banco com JPA-Hibernate
Tenho de persistir 1000 objetos de uma vez só e medir o tempo de persistencia, to uzando o Firebrid.
O processo ta funcionando corretamente mas acho que estou fazendo algo que ta deixando o processo pesado, e isso pode estar interfirindo no tempo de persistencia.
Acho que estou abrindo o banco a cada vez que persisto um objeto acho que teria de abrir uma vez só, mas não sei se é de propriedade do hibernate ter de abrir a cada inserção.
Vou enviar o código e se tiver como alguem me orientar melhor agradeço desde já.
esse é o dao

public class Dao {

    protected EntityManager em;
    private EntityManagerFactory emf;
    private final String NAME = "JFPU";

    /**Nome da Unidade de Persistencia**/
    public void open() {
        /**Abre Conexao com banco**/
        
        if (emf == null || !emf.isOpen()) {
            emf = Persistence.createEntityManagerFactory(NAME);
        }
        em = emf.createEntityManager();
        if (em == null) {
            try {
            } catch (RuntimeException e) {
                System.out.println(e.getMessage());
            }
        }
    }

    public void close() {
        /**Fecha Conexao com banco**/
        try {
            if (em != null) {
                em.close();
            }
            if (emf != null) {
                emf.close();
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

esse é o código do clienteDao

public void salvarCliente(Cliente cliente) { open(); // método hedado de Dao para abrir conexão com o banco de dados long init = 0; long end = 0; long diff; init = System.currentTimeMillis(); try { em.getTransaction().begin(); em.persist(cliente); } catch (Exception e) { System.out.println(e.getMessage()); em.getTransaction().rollback(); // desfaz transacao se ocorrer erro ao persitir } finally { if (em.getTransaction().isActive()) { em.getTransaction().commit(); } close(); end = System.currentTimeMillis(); diff = end - init; System.out.println("Tempo de resposta = " + (diff / 1000.0) + " segundos em JPA - Hibernate"); } }

aqui quando crio os 1000 itens a inserir

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jpa;

import Dao.ClienteDao;
import java.util.ArrayList;
import java.util.List;
import modelo.Cliente;

/**
 *
 * @author Carlos Sales
 */
public class incluir {

    public static void main(String[] args) {
        List<Cliente> clientes = new ArrayList<>();
        Cliente clienteA;
        long init = 0;
        long end = 0;
        long diff;
        init = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            clienteA = new Cliente();
            Cliente cliente = new Cliente();
            ClienteDao clienteDao = new ClienteDao();

            cliente.setBairro("Cambé V");
            cliente.setCelular("8428-5368");
            cliente.setCep("111111111-22");
            cliente.setCidade("Cambé");
            cliente.setComplemento("Casa");
            cliente.setContato("Ananias");
            cliente.setCpfcnpj("818181818181818");
            cliente.setEmail("[email removido]");
            cliente.setEndereco("Av. Patrocíneo Brandão Mac, 123");
            cliente.setEstado("PR");
            cliente.setNome("Carlos Alberto Sales");
            cliente.setNumero("328");
            cliente.setObs("Cliente antigo");
            cliente.setRgie("[telefone removido]");
            cliente.setSexo("M");
            cliente.setTelefone("3223-99000");

            clienteDao.salvarCliente(cliente);

            clientes.add(clienteA);
        }
        
    }
}

no aguardo.

11 Respostas

H

Vc acha?! O.o

Por que você não itera entre o entityManager.getTransaction.begin() e o commit()?
Assim você chama tudo uma vez só.

F

eu não costumo usar hibernate para processos em batch

prefiro fazer um pojo jdbc mesmo, que vai bem mais rápido

C

Então Hebert Coelho, tentei fazer entre o entityManager.getTransaction.begin() e o commit() mas, não consegui fazer porque como vou fazer para criar vários objetos nesse local?
em.persist(cliente);
aqui que eu não consigo para mandar vários clientes.

C

Então fabiozanardi
o caso de estudo é exatamente isso JPA x JDBC entende.
em jdbc eu fiz a iteração e deu certo ele abre apenas 1 x só ficou legal.
mas em JPA ta dando um erro.

R

carlosalbertosales:
Então fabiozanardi
o caso de estudo é exatamente isso JPA x JDBC entende.
em jdbc eu fiz a iteração e deu certo ele abre apenas 1 x só ficou legal.
mas em JPA ta dando um erro.

Você fez desse jeito e ele abriu uma vez só com JDBC? como assim? como está seu método salvar feito com JDBC?

H

carlosalbertosales:
Então Hebert Coelho, tentei fazer entre o entityManager.getTransaction.begin() e o commit() mas, não consegui fazer porque como vou fazer para criar vários objetos nesse local?
em.persist(cliente);
aqui que eu não consigo para mandar vários clientes.
Seu problema é mais de lógica do que de utilização.
Faça assim: public void persistirClientes(List<Person> pessoas){ entityManager.getTransaction().begin; for (Person person : pessoas) { entityManager.persist(person); } entityManager.getTransaction().commit(); } Se você fizer o mesmo para JDBC vai ficar pesado do mesmo modo.

C
Hebert Coelho , Permita me perguntar, no código que eu vou executar a chamada desse método eu tenho de enviar os 1000 objetos ?
public class incluir {

    public static void main(String[] args) {
        List<Cliente> clientes = new ArrayList<>();
        Cliente clienteA;
        long init = 0;
        long end = 0;
        long diff;
        init = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            clienteA = new Cliente();
            Cliente cliente = new Cliente();
            ClienteDao clienteDao = new ClienteDao();

            cliente.setBairro("Cambé V");
            cliente.setCelular("8428-5368");
            cliente.setCep("111111111-22");
            cliente.setCidade("Cambé");
            cliente.setComplemento("Casa");
            cliente.setContato("Ananias");
            cliente.setCpfcnpj("98989898989898");
            cliente.setEmail("[email removido]");
            cliente.setEndereco("Av. Patrocíneo Brandão Machado,2211");
            cliente.setEstado("PR");
            cliente.setNome("Carlos Alberto Sales");
            cliente.setNumero("328");
            cliente.setObs("Cliente antigo");
            cliente.setRgie("[telefone removido]");
            cliente.setSexo("M");
            cliente.setTelefone("3223-1122");

            clienteDao.salvarCliente(cliente);

            clientes.add(clienteA);
        }
        
    }
}
pode me dar uma explicação.
H
carlosalbertosales:
Hebert Coelho , Permita me perguntar, no código que eu vou executar a chamada desse método eu tenho de enviar os 1000 objetos ?
public class incluir {

    public static void main(String[] args) {
        List<Cliente> clientes = new ArrayList<>();
        Cliente clienteA;
        long init = 0;
        long end = 0;
        long diff;
        init = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            clienteA = new Cliente();
            Cliente cliente = new Cliente();
            ClienteDao clienteDao = new ClienteDao();

            cliente.setBairro("Cambé V");
            cliente.setCelular("8428-5368");
            cliente.setCep("111111111-22");
            cliente.setCidade("Cambé");
            cliente.setComplemento("Casa");
            cliente.setContato("Ananias");
            cliente.setCpfcnpj("98989898989898");
            cliente.setEmail("[email removido]");
            cliente.setEndereco("Av. Patrocíneo Brandão Machado,2211");
            cliente.setEstado("PR");
            cliente.setNome("Carlos Alberto Sales");
            cliente.setNumero("328");
            cliente.setObs("Cliente antigo");
            cliente.setRgie("[telefone removido]");
            cliente.setSexo("M");
            cliente.setTelefone("3223-1122");

            clienteDao.salvarCliente(cliente);

            clientes.add(clienteA);
        }
        
    }
}
pode me dar uma explicação.
Crie a lista e não fique chamando o clienteDao.salvarCliente(cliente); toda hora.

Tenha a lista toda na mão e depois crie um método como o que eu falei.

Do modo como você está fazendo, até no JDBC ele irá abrir e fechar uma transação para cada insert.

C
aqui eu crio a lista
for (int i = 0; i < 1000; i++) {
            clienteA = new Cliente();
            Cliente cliente = new Cliente();
            ClienteDao clienteDao = new ClienteDao();

            cliente.setBairro("Cambé V");
            cliente.setCelular("8428-5368");
            cliente.setCep("111111111-22");
            cliente.setCidade("Cambé");
            cliente.setComplemento("Casa");
            cliente.setContato("Ananias");
            cliente.setCpfcnpj("05.768.755/0001-54");
            cliente.setEmail("[email removido]");
            cliente.setEndereco("Av. Patrocíneo Brandão Machado,328");
            cliente.setEstado("PR");
            cliente.setNome("Carlos Alberto Sales");
            cliente.setNumero("328");
            cliente.setObs("Cliente antigo");
            cliente.setRgie("[telefone removido]");
            cliente.setSexo("M");
            cliente.setTelefone("3223-1371");
            clientes.add(clienteA);
        }

    }

como faço a chamada do metodo:

public void salvarCliente(List<Cliente> clientes) {
        open(); // método hedado de Dao para abrir conexão com o banco de dados
        long init = 0;
        long end = 0;
        long diff;
        init = System.currentTimeMillis();
        try {
            em.getTransaction().begin();
            for (Cliente cliente : clientes) {
                em.persist(cliente);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            em.getTransaction().rollback(); // desfaz transacao se ocorrer erro ao persitir
        } finally {
            if (em.getTransaction().isActive()) {
                em.getTransaction().commit();
            }
            close();
            end = System.currentTimeMillis();
            diff = end - init;
            System.out.println("Tempo de resposta = " + (diff / 1000.0) + " segundos em JPA - Hibernate");
        }
    }
C

Agradeço a todos que me ajudaram, o código ficou assim

package jpa;

import Dao.ClienteDao;
import java.util.ArrayList;
import java.util.List;
import modelo.Cliente;

/**
 *
 * @author Carlos Sales
 */
public class incluir {

    public static void main(String[] args) {
        List<Cliente> clientes = new ArrayList<>();
        Cliente cliente;
      
        ClienteDao clienteDao = new ClienteDao();
        for (int i = 0; i < 1000; i++) {
            cliente = new Cliente();
            cliente = new Cliente();
            cliente.setBairro("Cambé V");
            cliente.setCelular("8428-5368");
            cliente.setCep("111111111-22");
            cliente.setCidade("Cambé");
            cliente.setComplemento("Casa");
            cliente.setContato("Ananias");
            cliente.setCpfcnpj("05.768.755/0001-54");
            cliente.setEmail("[email removido]");
            cliente.setEndereco("Av. Patrocíneo Brandão Machado,328");
            cliente.setEstado("PR");
            cliente.setNome("Carlos Alberto Sales");
            cliente.setNumero("328");
            cliente.setObs("Cliente antigo");
            cliente.setRgie("[telefone removido]");
            cliente.setSexo("M");
            cliente.setTelefone("3223-1371");
            clientes.add(cliente);
        }
        clienteDao.salvarCliente(clientes);
    }
}
public void salvarCliente(List<Cliente> clientes) {
        open(); // método hedado de Dao para abrir conexão com o banco de dados
        long init = 0;
        long end = 0;
        long diff;
        init = System.currentTimeMillis();
        try {
            em.getTransaction().begin();
            for (Cliente cliente : clientes) {
                em.persist(cliente);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            em.getTransaction().rollback(); // desfaz transacao se ocorrer erro ao persitir
        } finally {
            if (em.getTransaction().isActive()) {
                em.getTransaction().commit();
            }
            close();
            end = System.currentTimeMillis();
            diff = end - init;
            System.out.println("Tempo de resposta = " + (diff / 1000.0) + " segundos em JPA - Hibernate");
        }
    }

Gostaria de saber como fecha o tópico.

H

Aqui não tem como fechar.

O máximo que você pode fazer é editar seu post inicial e escrever [RESOLVIDO]. Em geral, tem moderador que não gosta… Mas é muito utilizado.

Criado 11 de outubro de 2012
Ultima resposta 11 de out. de 2012
Respostas 11
Participantes 4