Obtaining Access to an Entity Manager

The BookDBAO object of the Duke’s Bookstore
application includes methods for getting the book data from the database and
updating the inventory in the database when books are sold. In order to perform
database queries, the BookDBAO object needs to obtain
an EntityManager instance.

The Java Persistence API allows developers to use annotations to identify
a resource so that the container can transparently inject it into an object.
You can give an object access to an EntityManager instance
by using the @PersistenceUnit annotation to inject
an EntityManagerFactory, from which you can obtain
an EntityManager instance.

Unfortunately for the web application developer, resource injection
using annotations can only be used with classes that are managed by a Java
EE compliant container. Because the web container does not manage JavaBeans
components, you cannot inject resources into them. One exception is a request-scoped
JavaServer Faces managed bean. These beans are managed by the container and
therefore support resource injection. This is only helpful if your application
is a JavaServer Faces application.

You can still use resource injection in a web application that is not
a JavaServer Faces application if you can do it in an object that is managed
by the container. These objects include servlets and ServletContextListener objects. These objects can then give the application’s
beans access to the resources.

In the case of Duke’s Bookstore, the ContextListener object
creates the BookDBAO object and puts it into application
scope. In the process, it passes to the BookDBAO object
the EntityManagerFactory object that was injected into ContextListener:

The JavaServer Faces version of Duke’s Bookstore gets access to
the EntityManager instance a little differently. Because
managed beans allow resource injection, you can inject the EntityManagerFactory instance into BookDBAO.

In fact, you can bypass injecting EntityManagerFactory and
instead inject the EntityManager directly into BookDBAO. This is because thread safety is not an issue with request-scoped
beans. Conversely, developers need to be concerned with thread safety when
working with servlets and listeners. Therefore, a servlet or listener needs
to inject an EntityManagerFactory instance, which is
thread-safe, whereas a persistence context is not thread-safe. The following
code shows part of the BookDBAO object included in
the JavaServer Faces version of Duke’s Bookstore:

As shown in the preceding code, an EntityManager instance
is injected into an object using the @PersistenceContext annotation.
An EntityManager instance is associated with a persistence
context, which is a set of entity instances that the entity manager is tasked
with managing.

The annotation may specify the name of the persistence unit with which
it is associated. This name must match a persistence unit defined in the application’s persistence.xml file.

The next section explains how the BookDBAO object
uses the entity manager instance to query the database.