Java Persistence API (JPA)
Background
It is very common for web applications to use a database to store long-term (persistent) data.
In a well-structured application, all the code to handle the database is kept together in what we usually call the persistence layer. In the past, a typical application has contained many lines of code that had to be written to perform functions such as inserting data into the database, updating data, and finding data that meets certain conditions. Since the data, when held in the program, normally consisted of objects, much of the code that was required was about converting tablular data fetched from a database into objects in the program (and vice versa). This was often very laborious to code and time-consuming to test, despite (in many cases) having a well-known common structure.
The Java Persistence API (JPA) solves many of these problems. Instead of writing lots of low-level JDBC code, JPA allows the programmer to specify any number of classes as being "entity classes". Objects of these classes can then be persisted to and from a database without much extra code. The only overhead is the addition of a number of annotations to the class declarations. In many cases, these annotations can be produced automatically by tools (e.g. NetBeans).
See my notes on Hibernate for a bit more on the history of JPA.
What does a JPA application typically consist of?
A JPA application typically has (in the Persistence layer of its Model component):
- a set of entity classes - objects of these classes represent the fundamental business objects of the application
- a set of data access objects (DAO) - these represent the functionality for storing and fetching objects of the entity classes to/from the database
- a single persistence unit - stored in the file
persistence.xml
, this contains configuration information about the entities being managed and the database being used
- an entity manager object (one per thread/HTTP request) - this object (provided by the JPA implementation) manages the storing and fetching of managed objects to/from the database
- a single entity manager factory - this is the object that uses the configuration information in the persistence unit to create new entity managers
If you are running JPA in a container (such as Glassfish), the container will automatically inject data access objects for you (when tagged with the @EJB annotation), and inject an entity manager wherever tagged with @PersistenceContext. (The container will create an appropriate entity manager factory automatically, using the information in the persistence unit.)
Typically to store some data in a database, your application would perform the following steps:
- Create a new object and populate its properties (e.g. using data received from the user interface)
- Obtain an appropriate data access object and ask that to store the object
- The DAO would obtain an entity manager and use its functionality to mark the object as persistent
- The entity manager would interact with the database to store the object in an appropriate place and at an appropriate time
Typically, to fetch some objects from a database, your application would perform the following steps:
- Obtain an appropriate data access object and ask it to fetch the required data.
- The DAO would obtain an entity manager and use its functionality to fetch one or more objects from the database
- Your application can then use the fetched object(s) as it wishes
Note that once an object is "managed" by an entity manager, if its value changes then updates will be automatically stored in the database. It is never necessary to tell the entity manager that an object has changed - the entity manager will work that out for itself.
What do I need to know about JPA?
The following is a (non-exhaustive) list of the JPA concepts you need to know about:
Entity classes
- Entity classes; the @Entity annotation
- How Java classes map on to database tables (the default and how you can specify it explicitly)
- How Java properties map on to database columns (the default and how you can specify it explicitly)
- How you specify the property(ies) that constitute the primary key of an object
- How you can get JPA to assign primary key values automatically
- Particular property annotations: @Temporal, @Transient
Entity relationships
- Relationship mapping
- Mapping one-to-one, one-to-many and many-to-many relationships between objects
- Eager and lazy relationships
- Ordering relationships
- Mapping inheritance relationships. The 3 inheritance strategies (single table, joined and table-per-class)
Managing persistent objects
- The Entity Manager interface
- Obtaining an entity manager (in a container-managed environment and in a non-container-managed environment)
- The entity life cycle (new, managed, detached, removed) and how objects can be moved from one state to another - see JPA state diagram
- Persisting, merging and removing entities
- Cascading events on persistent objects
- Queries expressed in JPQL
- JPQL: syntax (SELECT, FROM, WHERE, ORDER, GROUP); binding parameters
- Queries expressed by criteria
- Bulk update or deletion
- Named queries
Related issues
- Concurrency
- Versioning
- Transaction management (in a container-managed environment and in a non-container-managed environment)
- Optimistic and pessimistic locking
Configuration
- The EntityManagerFactory interface
- Format of persistence.xml
- Adding JPA libraries to your application
- Adding JPA implementation libraries (e.g. Hibernate or TopLink) to your application
- Setting up a container-managed web application using Glassfish
- Setting up a non-container-managed web application using Tomcat
Note that JPA is very much tied up with EJBs when used in a container-managed environment.
Problem solving advice
Reading
- David R. Heffelfinger, D R, Java EE 6 Development with NetBeans 7, Packt, 2011 (Chapter 6)
- Goncalves A, Beginning Java EE 7 , Apress, 2013
- Keith M, Schincariol M, Pro EJB 3 - Java Persistence API, Apress, 2006
- Java EE persistence tutorial: http://download.oracle.com/javaee/5/tutorial/doc/bnbpy.html
- http://java.sun.com/javaee/technologies/persistence.jsp
- http://netbeans.org/kb/docs/web/hibernate-jpa.html