Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Funcionamento do FetchType.EAGER

Por curiosidade alterei o mapeamento da classe Conta para "FetchType.EAGER" e executei a Query sem o comando "join fetch c.movimentacoes", e o Hibernate teve um comportamento diferente do que eu esperava, ele executou os n + 1 selects mas mostrou os System.out no final do Console.

Porque o EAGER não se comportou como o comando "join fetch c.movimentacoes" ?

Abaixo o código da Classe Conta:

package br.com.caelum.financas.modelo;

import java.util.List;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

@Entity
public class Conta {


    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;
    private String titular;
    private String numero;
    private String banco;
    private String agencia;

    @OneToMany(mappedBy="conta", fetch = FetchType.EAGER)
    private List<Movimentacao> movimentacoes;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getTitular() {
        return titular;
    }
    public void setTitular(String titular) {
        this.titular = titular;
    }
    public String getNumero() {
        return numero;
    }
    public void setNumero(String numero) {
        this.numero = numero;
    }
    public String getBanco() {
        return banco;
    }
    public void setBanco(String banco) {
        this.banco = banco;
    }
    public String getAgencia() {
        return agencia;
    }
    public void setAgencia(String agencia) {
        this.agencia = agencia;
    }

    public List<Movimentacao> getMovimentacoes() {
        return movimentacoes;
    }

}

Abaixo o código da Classe TesteMovimentacaoConta:

package br.com.caelum.financas.teste;

import java.util.Iterator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import br.com.caelum.financas.modelo.Conta;
import br.com.caelum.financas.modelo.Movimentacao;
import br.com.caelum.financas.util.JPAUtil;

public class TesteMovimentacaoConta {

    public static void main(String[] args) {

        EntityManager manager = new JPAUtil().getEntityManager();
        //Movimentacao movimentacao = manager.find(Movimentacao.class, 2);
        //System.out.println("Numero de Movimentações: " + movimentacao.getConta().getTitular() );

        //Conta conta = manager.find(Conta.class, 1);
        //System.out.println("Numero de Movimentações: " + conta.getMovimentacoes().size() );

        //Query query = manager.createQuery("select c from Conta c join fetch c.movimentacoes");
        Query query = manager.createQuery("select c from Conta c");
        List<Conta> contas = query.getResultList();
        for (Conta conta: contas) {
            System.out.println("Numero de Movimentações: " + conta.getMovimentacoes().size() );
        }
    }
}
1 resposta
solução!

Olá Clence !

Este é o comportamento do EAGER para cada linha da entidade Conta ele realizar um select com todas as Movimentações(n + 1), você está correta. Já com join fetch é montado um único comando que trará todas as informações. Use sempre join fetch para pegar uma lista é tido como boa pratica. Nunca anote o atributo com EAGER , porque a entidade pode mudar ou até outro sistema podem utilizar esse modelo não querendo a tabela de movimentação.

Um abraço, João.