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!!