@PersistenceContext injects an EntityManager into a managed Spring component, associating that field with a persistence context. Because an EntityManager is not thread-safe by itself, Spring supplies a thread-safe proxy for DAO use. section 14.2
Use the annotation with these lifecycle and transaction considerations:
- Place it on an EntityManager field in a DAO or service managed by the container. section 14.2
- Set type = PersistenceContextType.EXTENDED when the persistence context should remain for the bean's entire lifecycle. section 14.2 section 14.3
- Keep database interactions inside transaction boundaries; Spring enables annotation-driven transaction management and supplies a transaction manager. section 14.2
- Reuse the same injection pattern in a generic DAO hierarchy, where shared EntityManager operations support multiple entity types. section 14.3
Injecting an EntityManager into a DAO
@Repository @Transactional public class ItemDaoImpl implements ItemDao { @PersistenceContext(type = PersistenceContextType.EXTENDED) private EntityManager em; public Item getById(long id) { return em.find(Item.class, id); } } section 14.2
Listing 14.3 The ItemDaoImpl class
Path: Ch14/spring-jpa-dao/src/main/java/com/manning/javapersistence/ch14 /dao/ItemDaoImpl.java @Repository #1 @Transactional #1 public class ItemDaoImpl implements ItemDao { @PersistenceContext(type = PersistenceContextType.EXTENDED) #2 private EntityManager em; #2 @Override #3 public Item getById(long id) { #3 return em.find(Item.class, id); #3 } @Override #4 public List<Item> getAll() { #4 return (List<Item>) em.createQuery("from Item", Item.class) #4 .getResultList(); #4 } @Override #5 public void insert(Item item) { #5 em.persist(item); #5 for (Bid bid : item.getBids()) { #5 em.persist(bid); #5 } #5 } @Override #6 public void update(long id, String name) { #6 Item item = em.find(Item.class, id); #6 item.setName(name); #6 em.persist(item); #6 } @Override #7 public void delete(Item item) { #7 for (Bid bid : item.getBids()) { #7 em.remove(bid); #7 } #7 em.remove(item); #7 } @Override #8 public Item findByName(String name) { #8 return em.createQuery("from Item where name=:name", Item.class) #8 .setParameter("name", name).getSingleResult(); #8 } } #1 The <kbd>ItemDaoImpl</kbd> class is annotated with <kbd>@Repository</kbd> and <kbd>@Transactional</kbd>. #2 The <kbd>EntityManager em</kbd> field is injected in the application, as annotated with <kbd>@PersistenceContext</kbd>. Persistence type <kbd>EXTENDED</kbd> means the persistence context is kept for the whole lifecycle of a bean. #3 Retrieve an <kbd>Item</kbd> by its <kbd>id</kbd>. #4 Retrieve all <kbd>Item</kbd> entities. #5 Persist an <kbd>Item</kbd> and all its <kbd>Bid</kbd>s. #6 Update the <kbd>name</kbd> field of an <kbd>Item</kbd>. #7 Remove all the bids belonging to an <kbd>Item</kbd> and the <kbd>Item</kbd> itself. #8 Search for an <kbd>Item</kbd> by its <kbd>name</kbd>.
Inspect the complete ItemDaoImpl listing to see annotation placement alongside repository, transaction, and EntityManager operations. section 14.2
