LAZY com JTA, tem jeito?

5 respostas
townray

Fiz uma pesquisa no fórum e encontrei várias respostas sobre esse assunto, porém eu gostaria de conversar um mais profundamente sobre essa questão.

Estou usando EJB3. Tenho um DAO que possue os métodos de find, persist, merge etc. Daí tenho uma classe X EJB Stateless que recebe a injeção de um Entity Manager e repassa para o DAO fazer o serviço. Essa classe X é injetada em um Managed Bean que faz o seguinte: Faz uma busca por um CPF na classe Pessoa que possue um relacionamento 1xN Lazy com uma classe Emails. No meu JSP eu tenho um dataTable que renderiza os emails de Pessoa, porém quando o CPF já existe e o find retorna a classe Pessoa populada recebo o seguinte erro:

“Received ‘org.hibernate.LazyInitializationException’ when invoking action listener ‘#{controleBean.buscarPorCpfCnpj}’ for component 'j_id606’
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: br.com.saybien.modelos.pessoas.Pessoa.emails, no session or session was closed”

Estou usando JPA e controle de transação gerenciada pelo container (JTA), portanto não sou eu quem abre ou fecha sessão. Pesquisando no Livro “Enterprise JavaBeans 3.0” da editora O’Reilly, obtive a seguinte informação: “O problema dessa inicialização sob demanda pode ser resolvido de duas maneiras. A maneira óbvia é simplismente navegar pelos objetos relacionados necessários enquanto a instância de entidade continuar gerenciada por um contexto de persistência. A segunda maneira é realizar a carga imediata quando você consulta a entidade.” Peraí, se eu tenho que carregar os relacionamentos sempre dentro da mesma sessão JPA não faz o mínimo sentido eu ter relacionamentos sob-demanada (LAZY) concordam?

Alguém já passou por isso? Melhor eu botar EAGER em tudo mesmo ou estou modelando de forma errada meu projeto? Eu não gostaria de criar um StateFull Session Bean somente para estender meu contexto transacional… a não ser que tenha alguma outra forma de fazer isso.

grato.

5 Respostas

H

Bom dia…

Você está utilizando Jboss Seam?

Se não estiver dá uma olhada no padrão: Open Session in View
Que pode resolver o seu problema.

Valeu

townray

haamilton:
Bom dia…

Você está utilizando Jboss Seam?

Valeu

Não estou…

Nesse caso? :roll:

H

Dá uma olhada no padrão: Open Session in View - https://www.hibernate.org/43.html

Que pode resolver o seu problema.

Valeu

townray

Obrigado pelas tentativas de me ajudar, mas isso também não me serve pois eu uso JPA e Transação gerenciada pelo container.

mavcunha

Já passei por isso, e realmente há pouco o que se fazer utilizando apenas as informações colocadas nas Entities. Passar o fetch para EAGER fará com que o relacionamento anotado seja sempre carregado. Se isso é o seu requerimento então não há problema, mas se não for você incorrerá no problema N + 1 com JPA. A outra solução é criar, ao invés de um simples find() e então percorrer o objeto, uma query em JPQL que pega o objeto já populado utilizando “JOIN FETCH”.

[]´s Marco.

Criado 9 de setembro de 2009
Ultima resposta 11 de set. de 2009
Respostas 5
Participantes 3