1
resposta

Proxy hibernate

Eu tenho uma aplicação que possui JSF + EJB + JPA(hibernate) na parte arquitetural.

Em determinado ponto do sistema, eu tenho um objeto que tem várias listas.

Quando eu vou dar um view nesse objeto inteiro na tela, eu invoco um método que captura esse objeto completo. Para por exemplo, montar uma tela de visualização.

No entanto, eu tenho um serviço que eu exponho via Jax-RS, e nesse serviço eu componho somente as informação principais do objeto, sem capturar essas listas que o compõe.

Meu problema:

Após a captura pelo hibernate, finalizado o service (EJB) dentro do meu endpoint rest quando ele tenta montar o JSON ele acaba invocando essas listas e toma um LazyInicializationException. Se eu der um inspect no Objeto antes dele converter a lista fica com proxy aberto do hibernate ("com.sun.jdi.InvocationException occurred invoking method.").

Nesses casos eu tenho que setar null na mão. Em diversos pontos da aplicação eu tenho que fazer isso. Até mesmo numa listagem desse objeto no JSF.

Ele tenta pegar essas listas e o proxy vê que o entitymanger está fechado e devolve essa exceção.

Mas eu queria simplesmente que esse objeto estivesse NULL.

Minhas querys são planejadas e isso tem me dado alguns transtornos.

Já procurei em vários lugares e não consigo achar essa solução.

Alguma luz?

1 resposta

Oi Rachel! Tudo bem?

JPA/Hibernate funcionam assim: Quando você pede o objeto a sua camada de persistência com hibernate, em geral os relacionamentos não serão carregados antecipadamente (Eager) para evitar consumo excessivo de recursos.

Lembre que as estruturas de relacionamentos podem ser muito complexas e colocar Eager en tudo, vai deixar seu sistema muito lento e consumindo muitos recursos.

Mais quais são as alternativas.

Existem 2 que eu conheço:

1) OpenSessionInView. Esse é um padrão que permite você adicionar um filtro na sua aplicação web, e sempre que se tentar acessar o método Lazy, e a sessão do Hibernate já esteja fechada, ele compreende o erro e abre uma nova sessão apenas para trazer o resultado do relacionamento. (Sugerido para aplicações WEB)

2) Existe uma possibilidade de, ao invés de chamar o método que seleciona o objeto A, você criar um método que traz o objeto A mais o join com a relação através de uma HQL ou JPQL. (Sugerido para serviços WS)

Existem cursos muito bons de JPA e Spring na Altura, onde esses modelos são apresentados em detalhes.

Caso queira mais informações, estou à disposição.

Abraço e sucesso,

Rodrigo