web-dev-qa-db-fra.com

PersistenceUnit vs PersistenceContext

Dans quelques projets que j'utilise avec succès

@PersistenceUnit(unitName = "MiddlewareJPA")
EntityManagerFactory emf;
...
EntityManager entityManager = emf.createEntityManager();

pour obtenir EntityManager pour la connexion à la base de données, mais il y a quelques jours, j'essayais de déplacer mon projet vers Jboss EAP 6.2 et il n'a pas pu créer EntityManager. J'étais sur Google et j'ai trouvé que je devais essayer de changer @PersistenceUnit à

@PersistenceContext(unitName = "MiddlewareJPA")
private EntityManager entityManager;

pour obtenir EntityManager. Cela a fonctionné mais je ne sais pas pourquoi. Quelle est la différence entre PersistenceUnit et PersistenceContext? Quels sont les avantages et les inconvénients de chacun? Où devrions-nous utiliser l'un d'eux?

44
user2377971

Je ne sais pas comment cela fonctionne exactement dans le Java EE, mais au printemps, lorsque vous spécifiez l'annotation @PersistenceContext, Il injecte EntityManager. Où va-t-il get EntityManager? Il est faux d'en créer un EntityManager pour toute la durée de vie de l'application en appelant EntityManagerFactory.createEntityManager(). Ainsi, une implémentation spéciale de l'interface EntityManager est utilisée et instancié directement. Il a une référence locale de thread local mutable à un réelEntityManager. Les implémentations de méthodes redirigent simplement les appels vers ce réelEntityManager. Il existe un écouteur de servlet qui, avant chaque demande, obtient EM en appelant EMF.createEntityManager() et l'affecte à cette référence interne de EM spécial. Cet écouteur gère également transactions en appelant getTransaction().begin(), .commit() et .rollback() sur le réelEM. Il s'agit d'une description très simplifiée des Et je crois que ce conteneur JEE fait la même chose que Spring.

Dans le cas général, il est préférable d'injecter EntityManager, car avec EntityManagerFactory et @PersistenceUnit Vous devez créer/détruire EntityManager à chaque fois à la main et gérer les transactions aussi.

40
Alexey Andreev

PersistenceUnit injecte un EntityManagerFactory et PersistenceContext injecte un EntityManager. Il est généralement préférable d'utiliser PersistenceContext sauf si vous avez vraiment besoin de gérer manuellement le cycle de vie de EntityManager.

64
chrylis

EntityManager obtenu via @ PersistenceContext est appelé Container Managed EntityManager car le conteneur sera responsable de la gestion de "EntityManager". EntityManager obtenu via @ PersistenceUnit/entityManagerFactory.createEntityManager () est géré dans l'application par le développeur. (par exemple pour gérer le cycle de vie de EntityManager, libérer les ressources acquises par EntityManager, etc.).

9
Raj