Como resolver Hibernate/JPA dando um select/linha da tabela?

8 respostas
javamysqlhibernate
T

Ola,
Eu tenho uma tabela com 30 mil registros, quero gerar um arquivo de exportacao de dados em txt. Ao inves do Hibernate fazer SELECT * FROM produto, ele esta fazendo SELECT * FROM PRODUTO WHERE ID=?, isso 30 mil vezes. Tem como resolver isso? Ou vou ter que usar SQL nativo ou JDBC?

public interface ProdutoEmpresaRepository extends JpaRepository<ProdutoEmpresa, Integer> {
     @Query("select pe from ProdutoEmpresa pe where pe.empresa=?1 and pe.produto.bloqueiaVenda=false and pe.produto.excluido=false")
     public List<ProdutoEmpresa> findByProdutoAtivo(Empresa empresa);
}

Pois leva 15 minutos num processo que deveria levar 1 minuto no maximo.
Estou usando Spring Data-JPA com hibernate.

8 Respostas

I

Ueh, tira o pe.empresa=?1 do where

I

Tambem nao entendi

T

nao eh o where empresa id que esta dando o problema. pois antes de fazer o post, testei com o metodo findAll(), do JpaRepository, e o comportamento é o mesmo, um select para cara linha da tabela. Verifiquei o metodo que gera a carga da balanca toledo, ele tambem da um select para cada produto da tabela.

I

Posta sua entidade

T

Reescrevi aqui um bem basico para fazer simulacoes sem praticamente configuracao nenhuma. mas ocorre a mesma coisa. Vou postar as entidades desse que reescrevi. Enquanto nao tinha relacionamentos funcionou perfeito nao dava nem 1 segundo. Coloquei os relacionamento comecou a fazer um select para cada linha da tabela produto.

`
@Entity
public class Produto implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private Long codigoEan;
private String descricao;
private String descricaoReduzida;
private Boolean bloqueiaVenda;
private Boolean excluido;

}
`

`
@Entity
public class Empresa implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String razaoSocial;
private String nomeFantasia;
private String cnpj;

public Empresa() {
}

}
`

`
@Entity
public class ProdutoEmpresa implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@ManyToOne
private Produto produto;
@ManyToOne
private Empresa empresa;
private BigDecimal precoVenda;
private BigDecimal precoPromocao;

public ProdutoEmpresa() {
}

}
`

`
public class ProdutoDao implements Serializable {

public List<ProdutoEmpresa> listar() {
    Session sessao = HibernateUtil.getInstance().getSession();
    Query q = sessao.createQuery("select p from ProdutoEmpresa p");
    List<ProdutoEmpresa> produtos = q.list();
    sessao.flush();
    HibernateUtil.getInstance().fecharSessao(sessao);
    return produtos;
}

}

@ViewScoped
@ManagedBean
public class ProdutoController implements Serializable {

private Produto produto;
private List<ProdutoEmpresa> produtos;
private final ProdutoDao produtoDao = new ProdutoDao();

public ProdutoController() {
}

public String getCodigoEan() {
    return codigoEan;
}

public String getDescricao() {
    return descricao;
}

public Produto getProduto() {
    return produto;
}

public List<ProdutoEmpresa> getProdutos() {
    return produtos;
}

public void listar() {
    long t1 = System.currentTimeMillis();
    produtos = produtoDao.listar();
    for (ProdutoEmpresa p : produtos) {
        System.out.println(p.getProduto().getCodigoEan() + ";" + p.getProduto().getDescricao() + ";" + p.getProduto().getId() + ";"
                + (p.getProduto().getBloqueiaVenda() == true ? "SIM" : "NAO") + ";" + (p.getProduto().getExcluido() == true ? "SIM" : "NAO") + ";"
                + p.getPrecoVenda() + ";" + p.getPrecoPromocao());
    }
    long t2 = System.currentTimeMillis();
    System.out.println("TEMPO DE EXECUCAO:\t" + ((t2 - t1) / 100) / 60);
}

}
`

T

Achei a solucao no livro de Gilliard Cordeiro, Aplicacoes para web com jsf e jpa.
O problema era devido ao relacionamento, primeiro dava um select * from produtoempresa, depois dava um select para recuperar o produto. Alterei a jpql para

Query q = sessao.createQuery("select p from ProdutoEmpresa p join fetch p.produto join fetch p.empresa");

agora o select executando da um select * from produtoempresa inner join produto inner join empresa e a execucao leva 7 segundos.

I

ou vc poderia fazer por anotação, deixando os relacionamentos eager.
Veja o que será mais comum e configure o mesmo.

T

eu tentei fazer por anotacao usando o fetchtype.eager, mas ele nao faz o join. a unica forma que funcionou o join, foi fazendo assim

Criado 26 de agosto de 2016
Ultima resposta 27 de ago. de 2016
Respostas 8
Participantes 3