Resolvendo LazyInitializationException em 5 minutos

Olá Pessoal,

No post de hoje vamos ver como podemos resolver o LazyInitializationException em 5 minutos. Dificilmente um desenvolvedor não passou por essa exceção. Não vou entrar em detalhes sobre o motivo  da exceção LazyInitializationException, até por que já falei em um post aqui no blog, usando a solução com filter.

Lets go…

Na prática

Para mostrar a solução na prática, vou pegar um exemplo simples. Vamos considerar o relacionamento de que um Type  tem muitos Users, veja

@Entity

@Table(name = “type”)

public class Type implements java.io.Serializable { 

private static final long serialVersionUID = 2644022136811709451L; 

private Long id;

private String description;

private Set<User> users = new HashSet<User>(); 

public Type() {

}

@Id

@GeneratedValue

@Column(name = “ID”, unique = true, nullable = false)

public Long getId() {

return this.id;

}

@OneToMany(fetch = FetchType.LAZY, mappedBy = “type”,  targetEntity=User.class)

public Set<User> getUsers() {

return this.users;

}

//getters/setters omitidos

}

User.java

@Entity

@Table(name = “user”, uniqueConstraints = @UniqueConstraint(columnNames = “EMAIL”))

public class User implements java.io.Serializable,Comparable<User> { 

private static final long serialVersionUID = 9108778602728711429L; 

//declaração de variaveis omitidas 

@ManyToOne(fetch = FetchType.LAZY)

@JoinColumn(name = “TYPE_ID”,nullable=false)

public Type getType() {

return this.type;

}

//getters/setters omitidos

} 

Nada de especial até aqui, apenas o relacionamento que já conhecemos.

O problema

Agora que temos o problema, quando o User.java tentar acessar o Type e a conexão já foi fechada, já sabemos que vamos resolver LazyInitializationException. Uma forma para resolver é usando  join fetch, que evitará o problema pelo seguinte motivo:

– Apenas uma consulta será feita e evitamos o problema N + 1;

– A realização da consulta vai deixar de ser Lazy para Eager. Isso é diferente de você mudar de Lazy para Eager.

No DAO

Devemos ter a consulta assim:

public class UserDAO{

public List<User> readAll() {

                //avoiding LazyInitializationException join fetch

                String hql = “select u from User u join fetch u.type”;

                Query query = getCurrentSession().createQuery(hql);

                return query.list();

        }

}

Pronto. Resolvido seu problema com LazyInitializationException. Mas um detalhe importante é que para cada coleção que temos, é uma consulta que devemos ter. Se Type tem uma coleção de acesso, é uma consulta.

Bom é isso. Vou ficando por aqui e espero que tenham gostado do post.

Abraços, see ya!! 

Deixe um comentário

O seu endereço de e-mail não será publicado.