Tecnologia

O paradoxo do ResolveLazy

Por: , outubro 18, 2013

O Histórico

O conceito de “Entidade” — um objeto que representa uma linha de uma determinada tabela no banco de dados — sempre existiu em JavaEE. Porém, quando o desenvolvimento de aplicações no modelo JavaEE começou a se popularizar, os “Entity Beans” não tiveram a mesma aceitação dos outros componentes desta mesma arquitetura, como “Session Beans” e “Message Driven Beans”.

Motivos para baixa aceitação do conceito são :

1. A complexidade para se definir um “Entity Bean” era muito alta e dependia de muitas linhas de código.

2. Um Objeto, quando carregado, trazia consigo todas as suas relações com todos os outros objetos. Ou seja, quando se carregava para memória um objeto como “Cliente de banco”, ele trazia consigo todas as suas relações, como todas as contas e cada conta trazia consigo todas as movimentações, e assim por diante.

O JPA

Os “Entity Beans” do JavaEE entraram em desuso, abrindo espaço para que outros padrões de mapeamento “objeto-relacional” surgissem. Neste cenário, quem se destacou muito foi o Hibernate.

O Hibernate, além de ser muito fácil de configurar e fazer a tradução “objeto-relacional”, também trazia um conceito novo, o famoso “lazy retrieval”. Este conceito é muito simples e extremamente útil. Ele estabelece para cada relação de um objeto, se ela será carregada quando o Objeto for carregado.

Assim:

Na classe Cliente, pode-se anotar a relação com Telefone como “lazy”: quando um Cliente for carregado os “Telefones de Cliente” não são carregados, ou “eager”: quando um Cliente for carregado, os “Telefones de Cliente” são carregados.

O paradoxo do ResolveLazy

Com o conceito, surgiu o “problema”. Quando se tentava acessar uma relação configurada como “Lazy” fora do contexto do Hibernate, o mesmo não consegue carregar o objeto e lança a exceção “LazyInitializationException”.

Para evitar este problema, programadores inventaram o famoso “resolve lazy”: nas camadas de serviço passa-se a “inflar” o objeto inicial com as necessidades de tela.

O efeito prático disto é inflar um objeto com as necessidades de todas as telas onde o objeto é utilizado. Assim, em muito casos, carrega-se todas as relações deste objeto para memória, como se as relações deste fossem do tipo “Eager”.

Recapitulando, o Hibernate ficou famoso por introduzir o conceito de “lazy”, que faz com que não seja necessário carregar objetos e todas as suas relações para memória. Porém, programadores inventaram o antídoto para o conceito popular de “lazy” e inflam os objetos carregando todas as suas relações para memória!

Aí está o paradoxo.

 

Dicas para Evitar o problema

Trazer o dado sempre sem as suas relações, ou seja, manter o comportamento “lazy” do objeto. Assim, cada chamada ocupará menos  memória e apreasentará um desempenho e uma escalabilidade melhor.

Além disto, pode-se inverter o controle e deixar a tela pedir os dados necessários, pois uma tela sabe os dados que fazem parte de sua necessidade. Isto tem sido muito utilizado em aplicações que se utilizam da tecnologia “REST”.

Com estas dicas, pode-se evitar problemas com o “resolve lazy” e, assim, aumentar a escalabilidade de sua aplicação.

  • Receba nosso conteúdo em primeira mão.