Quatro soluções para LazyInitializationException

Carregar coleção por Open Session in View (Transaction View)

Open Session in View (ou Transaction View para outros) é um padrão de projeto onde você deixa a conexão aberta durante toda a requisição do usuário. Quando o acesso à lista for feito pela página o Hibernate irá realizar uma consulta no banco de dados sem problemas, nenhuma exceção será lançada.

Esse padrão de projeto para web utiliza uma classe que implementa a interface Filter; essa classe irá receber todas as requisições feitas ao servidor. O tratamento é bem simples e composto de duas ações básicas: abrir transação e finalizar transação.

Você precisa criar um Filter e adicionar suas configurações no arquivo “web.xml”. Veja abaixo como ficaria no código:

	<filter>
		<filter-name>ConnectionFilter</filter-name>
		<filter-class>com.filter.ConnectionFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>ConnectionFilter</filter-name>
		<url-pattern>/faces/*</url-pattern>
	</filter-mapping>
package com.filter;

import java.io.IOException;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.transaction.UserTransaction;

public class ConnectionFilter implements Filter {

	@Override
	public void destroy() {

	}

	@Resource
	private UserTransaction utx;

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		try {
			utx.begin();
			chain.doFilter(request, response);
			utx.commit();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {

	}
}
<h:dataTable var="dog" value="#{dataMB.person.lazyDogs}">
	<h:column>
		<f:facet name="header">
			Dog name
		</f:facet>
		#{dog.name}
	</h:column>
</h:dataTable>

Prós e contras dessa abordagem:

Prós

Contras

Não existe a necessidade de alteração no modelo

Todas as transações são controladas manualmente pelo filtro

É necessário ter bastante cuidado com erros nas transações. Uma mensagem de sucesso pode ser enviada pelo ManagedBean/Servlet e um erro acontecer no filtro.

Pode gerar o chamado n+1 de consultas. (Explicado abaixo)

O maior problema dessa abordagem é o fato do efeito chamando n+1. Quando retornamos uma pessoa para a página, a página irá iterar sobre a lista de dogs. Ao realizar o acesso a essa lista, uma nova consulta será efetuada no banco de dados para trazer todos os cachorros. Imagine se cada cachorro tivesse uma lista de Dogs indicando seus filhotes. Seria então feito outro select para trazer os filhotes. Mas caso os filhotes tenham outros filhotes, mais uma consulta…

Esse é o grande problema dessa “abordagem”. Uma consulta pode gerar um número quase infinito de outras consultas.

Essa abordagem funciona tanto para JEE como para JSE.

42 Thoughts on “Quatro soluções para LazyInitializationException

  1. Salvou meu dia!

    Parabéns pelo artigo!

Comment navigation

 

Leave a Reply

Post Navigation