Chapter 3. Java Persistence API Architecture
Prev | Part 2. Java Persistence API | Next

## Chapter 3. Java Persistence API Architecture

The diagram below illustrates the relationships between the primary components of the JPA architecture.

### Note

A number of the depicted interfaces are only required outside of an EJB3-compliant application server. In an application server, `EntityManager` instances are typically injected, rendering the `EntityManagerFactory` unnecessary. Also, transactions within an application server are handled using standard application server transaction controls. Thus, the `EntityTransaction` also goes unused.

- `Persistence`: The `jakarta.persistence.Persistence` class contains static helper methods to obtain `EntityManagerFactory` instances in a vendor-neutral fashion.

- `EntityManagerFactory`: The `jakarta.persistence.EntityManagerFactory` class is a factory for `EntityManager` s.

- `EntityManager` : The `jakarta.persistence.EntityManager` is the primary JPA interface used by applications. Each `EntityManager` manages a set of persistent objects, and has APIs to insert new objects and delete existing ones. When used outside the container, there is a one-to-one relationship between an `EntityManager` and an `EntityTransaction`. `EntityManager`s also act as factories for `Query` instances.

- `Entity` : Entities are persistent objects that represent datastore records.

- `EntityTransaction`: Each `EntityManager` has a one-to-one relation with a single `jakarta.persistence.EntityTransaction`. `EntityTransaction`s allow operations on persistent data to be grouped into units of work that either completely succeed or completely fail, leaving the datastore in its original state. These all-or-nothing operations are important for maintaining data integrity.

- `Query` : The `jakarta.persistence.Query` interface is implemented by each JPA vendor to find persistent objects that meet certain criteria. JPA standardizes support for queries using both the Java Persistence Query Language (JPQL) and the Structured Query Language (SQL). You obtain `Query` instances from an `EntityManager`.

The example below illustrates how the JPA interfaces interact to execute a JPQL query and update persistent objects. The example assumes execution outside a container.

Example 3.1. Interaction of Interfaces Outside Container

      // get an EntityManagerFactory using the Persistence class
      // It is not recommended to obtain a factory often, as construction of a
      // factory is a costly operation. Typically you will like to cache
      // a factory and then refer it for repeated use
      EntityManagerFactory factory = Persistence.createEntityManagerFactory(null);

      // get an EntityManager from the factory
      EntityManager em = factory.createEntityManager();

      // Begin a transaction
      em.getTransaction().begin();

      // query for all employees who work in our research division
      // and put in over 40 hours a week average
      Query query = em.createQuery("SELECT e " +
                                   "  FROM Employee e " +
                                   " WHERE e.division.name = 'Research' " +
                                   "   AND e.avgHours > 40");
      List results = query.getResultList();

      // give all those hard-working employees a raise
      for (Object res : results) {
        Employee emp = (Employee) res;
        emp.setSalary(emp.getSalary() * 1.1);
      }

      // commit will detect all updated entities and save them in database
      em.getTransaction().commit();

      // free the resources
      em.close();

Within a container, the `EntityManager` will be injected and transactions will be handled declaratively. Thus, the in-container version of the example consists entirely of business logic:

Example 3.2. Interaction of Interfaces Inside Container

    // query for all employees who work in our research division
    // and put in over 40 hours a week average - note that the EntityManager em
    // is injected using a @Resource annotation
    Query query = em.createQuery("select e from Employee e where "
        + "e.division.name = 'Research' and e.avgHours > 40");
    List results = query.getResultList();

    // give all those hard-working employees a raise
    for (Object res : results) {
        emp = (Employee) res;
        emp.setSalary(emp.getSalary() * 1.1);
    }

The remainder of this document explores the JPA interfaces in detail. We present them in roughly the order that you will use them as you develop your application.

## 1. JPA Exceptions

The diagram above depicts the JPA exception architecture. All exceptions are unchecked. JPA uses standard exceptions where appropriate, most notably `IllegalArgumentException`s and `IllegalStateException`s. The specification also provides a few JPA-specific exceptions in the `jakarta.persistence` package. These exceptions should be self-explanatory. See the Javadoc for additional details on JPA exceptions.

### Note

All exceptions thrown by OpenJPA implement `org.apache.openjpa.util.ExceptionInfo` to provide you with additional error information.

Prev | Up | Next
Chapter 2. Why JPA? | Home | Chapter 4. Entity