53

In few project I have been successfully using

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

to obtain EntityManager for Database connection, but some days ago I was trying to move my project to Jboss EAP 6.2 and it couldn't create EntityManager. I was googling it and I found that I should try change @PersistenceUnit to

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

to obtain EntityManager. It worked but I don't know why. What is the difference bettween PersistenceUnit and PersistenceContext? What are pros and cons of each one? Where should we be using one of them?

informatik01
  • 15,174
  • 9
  • 67
  • 100
user2377971
  • 1,362
  • 3
  • 20
  • 29
  • Consider adopting the CDI spec (new in JEE 6) to do your dependency injections so you have a more "universal" way of doing it in stead of a big pile of API/framework specific annotations. That doesn't really provide support for entity manager injections out of the box in JEE 6 itself, but there are documented ways of dealing with that. http://www.mastertheboss.com/cdi/cdi-and-jpa-tutorial – Gimby Jan 10 '14 at 09:52
  • 1
    As an addition to the available answers: here is an extremely useful article that can also help answer the OP's questions: [JPA Concepts](http://tomee.apache.org/jpa-concepts.html) – informatik01 Mar 11 '15 at 21:56

3 Answers3

77

PersistenceUnit injects an EntityManagerFactory, and PersistenceContext injects an EntityManager. It's generally better to use PersistenceContext unless you really need to manage the EntityManager lifecycle manually.

chrylis -cautiouslyoptimistic-
  • 67,584
  • 19
  • 106
  • 140
  • 1
    But if we have more than one persistance units then is there a way other than managing the EntityManagerFactory? – raj240 Nov 27 '19 at 16:11
  • To answer @raj240's question, we can inject the entity manager using the respective persistence unit's name @PersistenceContext(unitName = "MiddlewareJPA") – Rahul kalivaradarajalu Sep 30 '20 at 11:20
48

I don't know how it works exactly in the Java EE, but in Spring, when you specify @PersistenceContext annotation, it injects EntityManager. Where does it get EntityManager? It is wrong to create one EntityManager for the whole application lifetime by calling EntityManagerFactory.createEntityManager(). So instead a special implementation of EntityManager interface is used and instantiated directly. It has an internal mutable thread-local reference to a real EntityManager. Implementations of methods just redirect calls to this real EntityManager. And there is a servlet listener, that before each request obtain EM by calling EMF.createEntityManager() and assign it to that inner reference of special EM. Also this listener manages transactions by calling getTransaction().begin(), .commit() and .rollback() on the real EM. It is very simplified description of performed work. And I believe, that JEE container does the same thing, as Spring does.

In general case it is better to inject EntityManager, because with EntityManagerFactory and @PersistenceUnit you should create/destroy EntityManager every time by hands and manage transactions too.

Alexey Andreev
  • 1,785
  • 1
  • 16
  • 27
16

EntityManager obtained via @PersistenceContext is called Container Managed EntityManager as container will be responsible for managing "EntityManager". EntityManager obtained via @PersistenceUnit / entityManagerFactory.createEntityManager() is managed in the application by the developer. (for e.g. managing lifecycle of EntityManager, releasing the resources acquired by EntityManager, etc.).

Bharat
  • 118
  • 3
  • 16
Raj
  • 1,498
  • 3
  • 20
  • 38