Lazy loading não funciona (JPA)

Ola a todos,

tenho duas classes, Usuario e Curso, com um relacionamento N x M (ManyToMany), quando eu tento persistir um objeto Usuario que tem muitos cursos associados a ele, tudo funciona perfeitamente, mas quando eu tendo recuperar o mesmo objeto Usuario persistido anteriormente, o mesmo vem sem os cursos que estão relacionados a ele, no caso, quando eu chamo o método ‘getCursosResponsaveis’ da classe usuario em vez do método me retornar um objeto List populado com objetos do tipo Curso, ele me retorna um objeto do tipo IndirectList.

código das classes mensionadas:


@Entity
@Table(name = "P_USUARIO")
public class Usuario implements Serializable {

.....

@ManyToMany(fetch=FetchType.LAZY)
    @JoinTable(name="P_CURSO_RESPONSAVEL",
    inverseJoinColumns={
        @JoinColumn(name="ID_CURSO")},
    joinColumns={
        @JoinColumn(name="ID_USUARIO")})
    private List<Curso> cursosResponsaveis;

.....

}

@Entity
@Table(name="VW_P_CURSO", schema="lyceum_20062.")
public class Curso implements Serializable{
....

@ManyToMany(fetch=FetchType.LAZY, mappedBy="cursosResponsaveis", cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
    private List<Usuario> usuarios;

....

}

alguem pode me ajudar?
desde já obrigado pela atenção.

Vc esta utilizando um servidor de aplicação que utiliza para implementar a espec JPA o toplink.
Este comportamente é normal, pois o lazy loading so ira funcionar quando vc interar/utilizar esta sua lista, apenas chamar que retorna um list não funciona.
Mesme em debug vc não ira conseguir ver os objetos populados no seu list. É preciso utilizar/interar a collection.

Vc esta utilizando um servidor de aplicação que utiliza para implementar a espec JPA o toplink.
Este comportamente é normal, pois o lazy loading so ira funcionar quando vc interar/utilizar esta sua lista, apenas chamar que retorna um list não funciona.
Mesme em debug vc não ira conseguir ver os objetos populados no seu list. É preciso utilizar/interar a collection.

obrigado por responder Abdon.

agora voltando ao assunto, quando eu recupero o objeto usuario do banco, por padrão (fetch=lazy) ele não irá trazer nenhuma dependencia (cursos) desse objeto, certo? mas quando eu chamo o método get do respectivo atributo ele não deveria retornar essa lista preenchida com os respectivos objetos curso? segue exemplo:


 @Entity  
 @Table(name = "P_USUARIO")  
 public class Usuario implements Serializable {  
   
 .....  
   
 @ManyToMany(fetch=FetchType.LAZY)  
     @JoinTable(name="P_CURSO_RESPONSAVEL",  
     inverseJoinColumns={  
         @JoinColumn(name="ID_CURSO")},  
     joinColumns={  
         @JoinColumn(name="ID_USUARIO")})  
     private List<Curso> cursosResponsaveis;  

     public List<Curso> getCursosResponsaveis(){
         return cursosResponsaveis;
     }
   
 .....  


} 

Não, ele não deveria.
Ele so ira para o banco de dados quando vc fizer um:

List.get(index)

Ai sim ele vai para o banco recuperar os dados da sua lista.
Ele apenas ira recuperar quando vc [color=red][size=18]utilizar[/size][/color] a List, apenas chamar o metodo vgetCursosResponsaveis não ira fazer [color=red][color=yellow]nada[/color][/color]

no caso se eu fizesse isso:

.....
//supondo que existe um usuario com id = 1 e que esse usuário tenha muitos cursos relacionados a ele
Usuario user = entityManager.find(Usuario.class, 1);

List<Curso> test = user.getCursosResponsaveis();
.....

o objeto ‘test’ não daveria ser preenchido? ou ele retorna uma IndirectList mesmo?
no caso de ser a segunda opção, como eu deveria fazer para recuperar a lista de cursos associados a um objeto usuário?

Eu não sei direito o (até porque eu estou com o mesmo problema que vc) qual a razão q o TopLink faz essa cagada de serialização onutil. Além disso só recuperar a lista e fazer algo (qualquer coisa mesmo) não irá acontecer nada, pois a indirectList não está instanciada e vai lançar akelas exceptions do Toplink;; No Hibernate funciona mas no TopLink não.

No meu caso a única coisa que eu fiz é em ambas partes do relacionamento (nas duas tabelas) é trocar o fecth de LAZY por EAGER. (Lembre-se que sempre é LAZY por default)

Dá uma quebra de performance, mas funciona!

Tenta isso ae :smiley: