Um EntityManager pode ser gerenciado pelo container Java EE ou pela aplicação, a escolha de quem vai administrar suas instâncias depende das necessades do projeto. Desta maneira este post tem por objetivo apresentar as diferentes maneiras de criar instâncias e o que acontece nos bastidores desta API quando gerencida pelo container ou pela aplicação.

EntityManager, em tradução para Português do Brasil seria “gestora de entidades“, para facilitar, sera utilizado o termo “EntityManager” para representa-la.

Entidades são gerenciadas por EntityManager, que é representado por instâncias de javax.persistence.EntityManager. Cada instância de EntityManager está associado a um contexto de persistência, ou seja, um conjunto de instâncias de entidades gerenciadas que existam em uma base de dados. A interface EntityManager define métodos que são usados para interagir com o contexto de persistência.

A interface EntityManager

A API EntityManager por exemplo, cria, atualiza e remove instâncias persistentes de entidades, encontra entidades pela chave primária e permite utilizar mecanismos de consultas.

EntityManager gerenciado pelo container

Com um EntityManager gerenciado pelo container Java EE, o contexto de persistência de uma instância de EntityManager é propagada automaticamente pelo container para todos os componentes da aplicação que usam a instância de EntityManager dentro de uma transação única, Java Transaction API (JTA). Transações JTA geralmente envolvem chamadas entre os componentes da aplicação. Para completar uma transação JTA, esses componentes normalmente precisa de acesso a um único contexto de persistência. Isso ocorre quando um EntityManager é injetado nos componentes de aplicação por meio da anotação javax.persistence.PersistenceContext. O contexto de persistência é propagado automaticamente com uma transação JTA corrente e referências de EntityManager que são mapeadas para a mesma unidade de persistência, proporciona o acesso ao contexto de persistência dentro dessa transação. Ao propagar automaticamente o contexto de persistência, os componentes da aplicação não precisa passar referências a instâncias de EntityManager uns aos outros, em ordem, para fazer mudanças dentro de uma única transação. O container Java EE gerencia o ciclo de vida de um EntityManager.

Para obter uma instância de EntityManager, é preciso injetar uma referência a um EntityManager no componente de aplicação:

@PersistenceContext
EntityManager em;

EntityManager gerenciado pela aplicação

Por outro lado, com um EntityManager gerenciado pelo aplicação o contexto de persistência não é propagado para os componentes e o ciclo de vida das instâncias do EntityManager é gerenciado pela propria aplicação.

EntityManager gerenciado pela aplicação são usados quando os aplicativos precisam acessar um contexto de persistência que não é propagado com a transação JTA entre instâncias de EntityManager em uma unidade de persistência em particular. Neste caso, cada EntityManager cria um novo contexto de persistência isolado. O EntityManager e seu contexto de persistência são criados e destruídos explicitamente pela aplicação.

Para a aplicação criar instâncias de EntityManager, é necessário usar o método createEntityManager de javax.persistence.EntityManagerFactory.

Para obter uma instância de EntityManager, primeiro é preciso obter uma instância de EntityManagerFactory após injetá-lo em um componente da aplicação por meio da anotação javax.persistence.PersistenceUnit:

@PersistenceUnit
EntityManagerFactory emf;

Em seguida, um exemplo de como obter uma instância de EntityManager apartir de um EntityManagerFactory:

EntityManager em = emf.createEntityManager();

Como um EntityManager gerenciado pela aplicação não se propaga automaticamente no contexto de uma transação JTA, as aplicações precisam gerenciar manualmente o acesso ao gerenciador de transações JTA ao executar operações nas entidades. A interface javax.transaction.UserTransaction define métodos para iniciar, confirmar e reverter transações. Para injetar uma instância de UserTransaction criando uma variável de instância com a anotação @Resource:

@Resource
UserTransaction utx;

Para iniciar uma transação, chame o método “begin” a partir de uma instância de UserTransaction. Quando todas as operações da entidade estão completas, chame o método “commit” para confirmar a transação. O método “rollback” é usado para reverter uma transação corrente.

O exemplo a seguir mostra como gerenciar as transações em uma aplicação que usa um EntityManager gerenciado pela própria aplicação.

@PersistenceContext
EntityManagerFactory emf;

EntityManager em;

@Resource
UserTransaction utx;

em = emf.createEntityManager();
try {
	utx.begin();
	em.persist(suaEntidade);
	em.merge(suaSegundaEntidade);
	em.remove(suaTerceiraEntidade);
	utx.commit();
} catch (Exception e) {
	utx.rollback();
}

Importante
Instâncias de EntityManager não são thread-safe ao contrário de EntityManagerFactory que são thread-safe. Então declarar variáveis de EntityManager como static não só parece como não é uma boa escolha, todo o cuidado com o static é pouco :D.

Por enquanto é isso, até o próximo post.

Deixe um comentário

Campos obrigatórios são marcados *

Post Navigation