Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

LazyInicializationException do JPA resolvido com SessionScoped?

Primeiramente, parabéns ao Nico pela didática do curso. =D

Na 4ª aula, o problema do LazyInicializationException consequente do relacionamento LazyLoading e o escopo da requisição sendo Request foi resolvido fazendo o "recarregamento" do objeto livro no bean conforme ele é demandado.

Ok, imagino que essa seja uma solução adequada e talvez a que provê uma menor sobrecarga no servidor.

Porém, consegui resolver esse mesmo problema alterando o escopo do EntityManager de "RequestScoped" para "SessionScoped" no método produtor, ficou assim:

@Produces
@SessionScoped
public EntityManager getEntityManager() {
    return emf.createEntityManager();
}

Entendo que fazendo assim a conexão será reutilizada durante o ciclo de vida do usuário na aplicação. Criando então, um objeto EntityManager para cada usuário.

Minhas duvidas:

  • A minha solução representa algum problema de desempenho ou segurança?
  • Como posso monitorar o desempenho do servidor/aplicação?
  • Qual o impacto se eu mudar o escopo para ApplicationScoped e assim compartilhar a conexão com todos os usuário?
  • Onde posso encontrar um material completo para entender o cenário mais adequada para cada escopo do CDI?
5 respostas

Oi Fernando,

que bom que gostou do treinamento!

Sobre a sua implementação do Producer, vejo dois problemas nessa abordagem:

1- Escalabilidade:

Um EntityManager usa uma conexão por baixo dos panos. Se vc usa um EntityManager por usuário, vc vai ter apenas tantos usuários quanto o seu banco aguenta. Vc tbm não pode utilizar um Pool de conexões que te ajudar administrar conexões inválidas.

2 - Memória:

O EntityManager guarda os objetos, ele é stateful. Com sua implementação o EntityManager fica guardando os objetos das requisições anteriores (ou vc faz um clear() em algum momento).

O EJB oferece uma forma parecida com a sua para gerenciar um EntityManager. Vc pode associar um EntityManager com um Session Bean Stateful. Isso se chama de Extended PersistenceContext. Enquanto o Session Bean Stateful vive, vive o EntityManager. No entanto, isso não fez muito sucesso no mercado.

Abs, Nico

Interessante! Então o EntityManager com escopo de sessão não seria uma boa solução, pois tem problemas de desempenho e escalabilidade.

Obrigado pela ajuda!

Nico, só mais uma questão relativa a essa dúvida.

Como posso monitorar o desempenho da plicação? No sentido de visualizar quantos EntityManagers estão instanciados, objetos gerenciados pelo CDI também... Você tem alguma dica quanto a isso?

Abraços.

solução!

Oi Fernando,

através dos Hibernate Statistics vc consegue recuperar alguns dados sobre o uso da sua camada de persistencia. No treinamento JPA II falamos um pouco sobre isso:

https://cursos.alura.com.br/course/jpa-avancado/section/8

acho que isso é o caminho mais fácil.

Se vc usa mysql tbm há comandos como o show processlist para ver as conexões abertas. sei tbm que o pool de conexões C3P0 possui formas de monitoramento (se vc usa C3P0).

abs

Ah legal! vou dar uma olhada nesses recursos.

Obrigado pela ajuda, até mais.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software