EntiyManager, qual o modo correto de se utilizar em uma aplicação Java EE?

1 resposta
M

Boa noite pessoal, uma dúvida que sempre tive com relação ao EntityManager foi sobre seu escopo em um ambiente J2EE não gerenciado.
Abrir e fechar a cada transação? Abrir e fechar a cada operação de negócio? Abrir e fechar a cada Requisição HTTP?

Andei lendro sobre isso mas não encontrei uma resposta clara (ou não consegui entender :frowning: ).

Suponha que tenho uma aplicação com struts 2 e hibernate, e quando vou persistir o objeto X a seguinte sequência de acontende:

action -> bo -> dao

Bem, se eu fechar a cada transação, se o objeto X possuir uma lista LAZY e eu fizer X.getLista() na minha action vou obter um org.hibernate.LazyInitializationException.
Além disso este modo me traria outro problema:

Se uma operação de negócios envolver várias entidades e ocorrer um erro na persistência de alguma, um rollback não teria o resultado esperado, pois o escopo não envonve a operação toda, ele é para cada entidade.

Neste caso uma solução seria criar o entiry manager na camada BO e injetálo no DAO?
Ou ainda utilizar somente um EntityManager para a requisição http?

Atualmente estou abrindo um EntityManager para cada dao mas não estou fechando eles, isso é aceitável?

Agradeço a contribuição.
Abraços

1 Resposta

Alessandro_Lazarotti

Para evitar problemas de Lazy em páginas você pode usar patterns como o Open Session in View: http://community.jboss.org/wiki/OpenSessioninView

Existem muitos frameworks para lhe ajudar com JPA/Hibernate, como o Seam por exemplo. Ele faz gerenciamento de transação, injeta EntityManager controlando todo seu ciclo de vida, sem vc precisar se preocupar em finalizar o EntityManager e tbm prevê a aplicação contra erros do tipo LIE nas páginas, sem vc ter que implementar o pattern que sugeri acima. Leia um pouco aqui: http://docs.jboss.org/seam/2.1.2/reference/en-US/html/persistence.html

Se vc não usa framework algum com o EntityManager, cuidado, vc NÃO deve manter seus EntityManagers abertos. Se vc fazer isso, em pouco tempo vc vai ter sérios problemas com pool de conexões, uma vez que vc obtem uma sessão com o banco e não devolve para o pool. A recomendação é que vc trabalhe com um entitymanager ativo por “Unit of Work”, ou seja, a atomicidade de uma operação do usuário com o sistema… geralmente em aplicações web isso se dá em um ciclo de request e response. Se sua transaçao é maior do que isso, vc pode armazenar o contexto de seu entitymanager provisóriamente na sessão web, e depois fecha-lo no final da transação. Frameworks como o Seam e o SpringWebFlow fazem parecido quando precisam lidar com Transações Extendidas e podem ajudar tbm nestes casos.

Um livro que sempre indico, qual aborda este e outros temas relevantes sobre JPA e Hibernate é o JavaPersistence With Hibernate (ele tbm possui uma versão traduzida). Ele explica em detalhes a abordagem JavaSE e Java EE para se trabalhar com JPA.

Criado 21 de abril de 2010
Ultima resposta 21 de abr. de 2010
Respostas 1
Participantes 2