FetchType.LAZY

Hello galera.
Estive dando uma olhada no SQL gerado pela consulta e gostaria de saber o porque desse retorno.
Eu tenho duas tabelas Centros e Universidade e seus relacionamentos estao abaixo;

Classe Centros
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="id_universidade",nullable=false)
private Universidade universidade;

Classe Universidade
@OneToMany(mappedBy="universidade", fetch = FetchType.EAGER)
@Cascade(CascadeType.SAVE_UPDATE)
private Collection<Centros> centros;

Quando eu executo esse codigo
Centros c = (Centros) session.get(Centros.class, 21) o SQL gerado e:

Hibernate:
    select
        centros0_.id_centro as id1_1_1_,
        centros0_.nome as nome1_1_,
        centros0_.data as data1_1_,
        centros0_.id_universidade as id4_1_1_,
        universida1_.id_universidade as id1_0_0_,
        universida1_.nome as nome0_0_
    from
        SYSTEM.Centros centros0_,
        SYSTEM.Universidade universida1_
    where
        centros0_.id_universidade=universida1_.id_universidade
        and centros0_.id_centro=?
Hibernate:
    select
        centros0_.id_universidade as id4_1_,
        centros0_.id_centro as id1_1_,
        centros0_.id_centro as id1_1_0_,
        centros0_.nome as nome1_0_,
        centros0_.data as data1_0_,
        centros0_.id_universidade as id4_1_0_
    from
        SYSTEM.Centros centros0_
    where
        centros0_.id_universidade=?

Agora a questao é a seguinte. Porque que ele efetua essa consulta marcada de vermelho? Eu notei que foi porque a classe Universidade esta marcada com EAGER, mas eu ja tenho esse dado no primeiro select porque a classe Centros é EAGER tbem.

Obrigado

Olá!

O problema aqui é que os dois relacionamentos estão como EAGER. Quando voce dá um get em Centros.class ele pega junto a Universidade relacionada (primeiro select).

Mas a Collection dentro da Universidade tambem esta como EAGER, entao alem de pegar os dados "simples’ da Universidade ele tambem precisa pegar todos os centros relacionados a essa Universidade (segundo select).

Note que a Universidade tem uma colecao de Centros e nao apenas um Centros, por isso que o Centros devolvido no primeiro select nao eh suficiente para popular a colecao e precisa do segundo select.

Se o relacionamento fosse OneToOne ele nao precisaria de dois selects…

A questao agora eh: vc realmente precisa que a colecao esteja como EAGER?

PS. ultima coisa: me parece que o nome mais adequado para sua classe seja Centro, no singular…

[]'s

Sérgio Lopes

Opa. E ae Sergio.
Obrigado pela resposta. A minha maior duvida nesse exemplo foi porque quando eu pedi para ele (session) excluir um Centro ele deu esse erro:

session.delete(c);
org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [teste.Centros#1]

Ou seja, primeiro eu tinha que retirar um Centro de uma colecao da tabela Universidade para depois eu excluir da tabela Centros.
Depois eu reparei que se eu mudasse os dois fetch`s para LAZY ele dao dava o erro e eu poderia excluir normalmente, com isso Sergio porque com o EAGER dava o erro e com o LAZY nao?

Mais uma coisa aproveitando a oportunidade. Esse caso foi de um teste e no link abaixo eu tenho uma duvida de um projeto que eu estou fazendo e ficaria muito feliz se voce ou outra pessoa me ajudasse. O link esta abaixo.
http://www.guj.com.br/posts/list/71329.java

Obrigado.