FetchType.LAZY esta trazendo tudo

6 respostas
F

Pelo que li o FetchType.Lazy não deveria trazer todos os filhos, porém esta fazendo isso!!O que há de errado!!

import java.util.ArrayList;
import java.util.List;

import javax.persistence.*;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;


@Entity
@Table(name="pessoa")
public class Pessoa {
	
	@Id
    @GeneratedValue(strategy = GenerationType.AUTO)  
	private int id;
	@Column(name="nome")
	private String nome;
	
	@Cascade(CascadeType.ALL)
	@OneToMany(mappedBy="pessoa",fetch=FetchType.LAZY) 
    private List<Endereco> enderecos = new ArrayList<Endereco>();
	
	
	

	public void setNome(String nome) {
		this.nome = nome;
	}
	public String getNome() {
		return nome;
	}
	public void setEnderecos(List<Endereco> enderecos) {
		this.enderecos = enderecos;
	}
	public void addEnderecos(Endereco endereco){
		this.enderecos.add(endereco);
	}
	
	public List<Endereco> getEnderecos() {
		return enderecos;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getId() {
		return id;
	}  
	
	

}
/////////////////////
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

@Entity
@Table(name="endereco")
public class Endereco {
	@Id
    @GeneratedValue(strategy = GenerationType.AUTO)  
	private int id;
	@Column(name="rua")
	private String rua;
	@Column(name="pais")
	private String pais;
	
	
	@ManyToOne(fetch=FetchType.LAZY)
	@Cascade(CascadeType.SAVE_UPDATE)
	@JoinColumn(name="fk_cidade")
	private Cidade cidade;
	
	
	
	@ManyToOne(fetch=FetchType.EAGER)
	@Cascade(CascadeType.SAVE_UPDATE)
	@JoinColumn(name="fk_pessoa")
	private Pessoa pessoa;
	
	public void setRua(String rua) {
		this.rua = rua;
	}
	public String getRua() {
		return rua;
	}
	public void setPais(String pais) {
		this.pais = pais;
	}
	public String getPais() {
		return pais;
	}
	public void setCidade(Cidade cidade) {
		this.cidade = cidade;
	}
	public Cidade getCidade() {
		return cidade;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getId() {
		return id;
	}
	public void setPessoa(Pessoa pessoa) {
		this.pessoa = pessoa;
	}
	public Pessoa getPessoa() {
		return pessoa;
	}

}

6 Respostas

Leo22

Voce ta tentando fazer o que?
uma busca de pessoas por endereço?
tem como explicar melhor?

F

Vc esta rodando em standalone? Digo fora de um server EE (tipo glassfish)? Se for o caso procure a respeito de weaving, ele fará que o lazy funcione corretamente

F

fausto,
Na real, estou testando da forma mais simples, ou seja, em um método estático em uma classe comum só para fins didáticos.
Lí em todos os tutoriais até o momento que o Lazy não traz os filhos, mas ao buscar a pessoa com seu endereço todos vêm juntos.
O que me deixou perplexo, essa lógica é aplicada somente quando se trata de um cliente fazendo uma solicitação para um servidor?

F
List<Pessoa>lista = HibernateUtil.getlist("Pessoa");
       for(Pessoa pe:lista){  
	     System.out.println(pe.getNome());
         for(Endereco e:pe.getEnderecos()){
	      System.out.println(e.getPais());
         }
       }
Esta me retornando todas as pessoas com todos os seus endereços. O que esta de errado na anotação
F

fabioEM:
List<Pessoa>lista = HibernateUtil.getlist("Pessoa"); for(Pessoa pe:lista){ System.out.println(pe.getNome()); for(Endereco e:pe.getEnderecos()){ System.out.println(e.getPais()); } }
Esta me retornando todas as pessoas com todos os seus endereços. O que esta de errado na anotação

Opa FabioEM, existem dois pontos:

Primeiro, Se vc estiver ainda com a sessão ativa ele irá carregar as entidades associadas se vc chamar, isso ocorre até mesmo qdo se usa o debug e tenta ver o que contem dentro da lista, ou seja cuidado pois ao testar a funcionalidade sem querer vc acaba carregando as entidades.
No caso do eclipselink que é outra implementação do jpa, e que eu uso, mesmo que vc de um close no entitymanager e no factory, se vc tentar iterar pelas associações ele volta a se conectar ao banco e as carrega. Uma forma mais garantida de testar essa questão é habilitando o log do hibernate, veja na documentação, assim vc saberá exatamente o que foi carregado e qual query foi criada para tal, é assim que eu faço para o eclipselink.

Segundo, a documentação diz que o lazy é uma “dica” a engine da persistencia, ou seja não precisa ser respeitada e cabe à implementação decidir sobre isso. No caso do eclipselink, se vc usar em standalone - o mesmo que vc está fazendo mas com o hibernate - o lazy NUNCA funciona, a menos que vc utilize o static weaving que altera as suas classes. Creio que o hibernate funcione assim tb, ou seja procure por weaving (dinamic ou static) e veja como deve ser configurado. No eclipselink eu uso um script do ant para compilar e executar o static weaving.

Espero que tenha ajudado :wink:

F

fausto,
blz, ajudou sim. Vou procurar por weaving (dinamic ou static) e depois te digo :lol:

Criado 11 de fevereiro de 2011
Ultima resposta 13 de fev. de 2011
Respostas 6
Participantes 3