Extended Persistence Context の使い道
JSR-220 JPA(Java Persistence API)では、Persistence Contextという概念が定義されています。これはTransaction Contextのアナロジーで、永続オブジェクトを管理する単位となります(Persistence Contextはトランザクションとは独立であることに注意) 。
Persistence Contextを管理するのがEntity Managerであり、JPAではまさにこのEntity ManagerのAPIを定義しています。Java EE環境では、Dependency InjectionやJNDIという手段で、コンポーネント間でPersistence Context(を管理するEntity Manager)を伝播させることができます。このようにJava EEコンテナによって管理されるEntity ManagerをContainer-Managed Entity Managerと呼びます。
Persistence ContextにはTransaction-scoped Persistence ContextとExtended Persistence Contextの2種類があります。Transaction-scopedの方は文字通りトランザクション単位での管理です。一方、Extendedの方は、コンテナによってcloseされるかまたはEntityManager APIで明示的にcloseされるまで、トランザクションをまたがって管理することが可能です。
Extended Persistence ContextはWebアプリでのエンティティのキャッシュ*1として使えます。具体的には、Stateful SessionBeanとExtended Persistence Contextを組み合わせることによってリクエストをまたがったConversation状態の保持が可能になります。次の例はJPA Proposed Final Draft 5.8.2から引用したものです。
5.8.2 Container-managed Extended Persistence Context @Stateful @Transaction(REQUIRES_NEW) public class ShoppingCartImpl implements ShoppingCart { @PersistenceContext(type=EXTENDED) EntityManager em; private Order order; private Product product; public void initOrder(Long id) { order = em.find(Order.class, id); } public void initProduct(String name) { product = (Product) em.createQuery("select p from Product p where p.name = :name") .setParameter("name", name) .getSingleResult(); } public LineItem createLineItem(int quantity) { LineItem li = new LineItem(order, product, quantity); order.getLineItems().add(li); return li; } }
参考:
- The new EJB 3 Persistence API (Michael KeithらによるBeJUGプレゼン資料)
- Stateful Session Beans Rock (Gavin Kingのblog)