Identify correct and incorrect statements or examples about application-managed persistence contexts.

[Note]

When an application-managed entity manager is used, the application interacts directly with the persistence provider's entity manager factory to manage the entity manager lifecycle and to obtain and destroy persistence contexts.

All such application-managed persistence contexts are EXTENDED in scope, and may span MULTIPLE transactions.

The EntityManager close and isOpen methods are used to manage the lifecycle of an application-managed entity manager and its associated persistence context.

The EntityManager.close() method closes an entity manager to release its persistence context and other resources. After calling close(), the application MUST NOT invoke any further methods on the EntityManager instance except for getTransaction and isOpen, or the IllegalStateException will be thrown. If the close() method is invoked when a transaction is active, the persistence context remains managed until the transaction completes.

The EntityManager.isOpen() method indicates whether the entity manager is open. The isOpen() method returns true until the entity manager has been closed.

The extended persistence context exists from the point at which the entity manager has been created using EntityManagerFactory.createEntityManager until the entity manager is closed by means of EntityManager.close. The extended persistence context obtained from the application-managed entity manager is a stand-alone persistence context - it is not propagated with the transaction.

When a JTA application-managed entity manager is used, if the entity manager is created outside the scope of the current JTA transaction, it is the responsibility of the application to associate the entity manager with the transaction (if desired) by calling EntityManager.joinTransaction.

Example of application-managed Persistence Context used in Stateless Session Bean:

/*
 * Container-managed transaction demarcation is used.
 * Session bean creates and closes an entity manager in
 * each business method.
 */
@Stateless
public class ShoppingCartImpl implements ShoppingCart {

	@PersistenceUnit
	private EntityManagerFactory emf;

	public Order getOrder(Long id) {
		EntityManager em = emf.createEntityManager();
		Order order = (Order)em.find(Order.class, id);
		em.close();
		return order;
	}

	public Product getProduct() {
		EntityManager em = emf.createEntityManager();
		Product product = (Product) em.createQuery("select p from Product p where p.name = :name")
			.setParameter("name", name)
			.getSingleResult();
		em.close();
		return product;
	}

	public LineItem createLineItem(Order order, Product product, int quantity) {
		EntityManager em = emf.createEntityManager();
		LineItem li = new LineItem(order, product, quantity);
		order.getLineItems().add(li);
		em.persist(li);
		em.close();
		return li; // remains managed until JTA transaction ends
	}
}					
					

Another example of application-managed Persistence Context used in Stateless Session Bean:

/*
 * Container-managed transaction demarcation is used.
 * Session bean creates entity manager in PostConstruct
 * method and clears persistence context at the end of each
 * business method.
 */
@Stateless
public class ShoppingCartImpl implements ShoppingCart {

	@PersistenceUnit
	private EntityManagerFactory emf;

	private EntityManager em;

	@PostConstruct
	public void init()
		em = emf.createEntityManager();
	}
	
	public Order getOrder(Long id) {
		Order order = (Order)em.find(Order.class, id);
		em.clear(); // entities are detached
		return order;
	}
	
	public Product getProduct() {
		Product product = (Product) em.createQuery("select p from Product p where p.name = :name")
			.setParameter("name", name)
			.getSingleResult();
		em.clear();
		return product;
	}
	
	public LineItem createLineItem(Order order, Product product, int quantity) {
		em.joinTransaction();
		LineItem li = new LineItem(order, product, quantity);
		order.getLineItems().add(li);
		em.persist(li);
		// persistence context is flushed to database;
		// all updates will be committed to database on tx commit
		em.flush();
		// entities in persistence context are detached
		em.clear();
		return li;
	}

	@PreDestroy
	public void destroy()
		em.close();
	}
}
					

Example of application-managed Persistence Context used in Stateful Session Bean

//Container-managed transaction demarcation is used
@Stateful
public class ShoppingCartImpl implements ShoppingCart {

	@PersistenceUnit
	private EntityManagerFactory emf;

	private EntityManager em;

	private Order order;

	private Product product;

	@PostConstruct
	public void init() {
		em = emf.createEntityManager();
	}
	
	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) {
		em.joinTransaction();
		LineItem li = new LineItem(order, product, quantity);
		order.getLineItems().add(li);
		return li;
	}

	@Remove
	public void destroy() {
		em.close();
	}
}
					

Example of application-managed Persistence Context with Resource Transaction

// Usage in an ordinary Java class
public class ShoppingCart {

	private EntityManager em;

	private EntityManagerFactory emf;

	public ShoppingCart() {
		emf = Persistence.createEntityManagerFactory("orderMgt");
		em = emf.createEntityManager();
	}
	
	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) {
		em.getTransaction().begin();
		LineItem li = new LineItem(order, product, quantity);
		order.getLineItems().add(li);
		em.getTransaction().commit();
		return li;
	}
	
	public void destroy() {
		em.close();
		emf.close();
	}
}					
					

To summarize comparison of container- and application-managed EntityManagers:

  1. Application-managed EntityManager

    • The lifecycle of EntityManager - EntityManagerFactory

    • Transaction тАУ JTA or Resource-local

    • Persistence Context - EntityManager.clear()

  2. Container-managed EntityManager

    • Container manages lifecycle of EntityManager, Transaction

    • JTA Transaction ONLY

    • Transaction-scoped persistence context (by default)

    • Extended persistence context (only in Stateful Session bean) - keeps entities managed across multiple transaction.

Professional hosting     Belorussian informational portal         Free SCWCD 1.4 Study Guide     Free SCDJWS 1.4 Study Guide     SCDJWS 1.4 Quiz     Free IBM Certified Associate Developer Study Guide     IBM Test 000-287. Enterprise Application Development with IBM WebSphere Studio, V5.0 Study Guide     Free Mock Exam Engine