Se tem uma coisa que você precisa entender para usar com sucesso a JPA (Java Persistence API), é o conceito de Cache. Infelizmente o cache é uma estrutura interna, não exposta pela JPA via código.
O que você tem que ter em mente sobre o cache da JPA:
- Um Cache é uma cópia de dados, uma cópia desconectada do banco de dados.
- Flushing é o ato de levar as modificações feitas em cache para o banco de dados.
- Um PersistenceContext é, essencialmente, um Cache.
- Um EntityManager represetne um PersistenceContext (logo, um cache).
- Um EntityManagerFactory cria um EntityManager (e todavia um PersistenceContext/Cache).
Comparando os contextos de persistência RESOURCE_LOCAL e JTA.
Com <persistence-unit transaction-type="RESOURCE_LOCAL"> você é que se responsabiliza por criar e rastrear o EntityManager (PersistenceContext/Cache).- Você precisa usar o EntityManagerFactory para obter um EntityManager.
- A instância do EntityManager obtida é um PersistenceContext/Cache.
- Um EntityManagerFactory pode ser injetado com a anotação @PersistenceUnit apenas (sem @Persistence Context).
- Não é permitido usar @PersistenceContext para se referir a uma unit do tipo RESOURCE_LOCAL.
- Você deve usar EntityTransaction API para iniciar/comitar todas as chamadas para seu ENtityManager.
- Chamar ENtityManagerFactory.createEntityManager() duas vezes resulta em duas instâncias separadas de EntityManager e, é claro, dois PersistenceContext/Caches separados.
- Não é uma boa idéia ter mais de uma instânciade um EntityManager em uso (não crie um segundo EntityManager antes de destruir o primeiro).
Com <persistence-unit transaction-type="JTA"> o container irá cuidar da criação e do rastreamento do EntityManager para você, e neste caso:
- Você não pode usar o EntityManagerFactory para obter um EntityManager.
- Você só pode ter o EntityManager que é fornecido pelo container.
- Um EntityManager pode ser injetado pela anotação @PersistenceContext, somente (sem @PersistenceUnit).
- Você não pode usar @PersistenceUnit para fazer referência a uma unit do tipo JTA.
- O EntityManager fornecido pelo container é uma referência ao PersistenceContext/Cache associado a transação JTA.
- Se não há transações JTA em progresso, o EntityManager não pode ser usado porque não há PersistenceContext/Cache.
- Qualquer um com uma referência para a mesma unit na mesma transação irá automaticamente ter uma referência para o mesmo PersistenceContext/Cache.
- O PersistenceContext/Cache é flushed e limpo a cada commit JTA.
É isso aí! Mais informações e exemplos veja em http://tomee.apache.org/jpa-concepts.html