CRUD Database Operations with JPA
Given an EntityManager
javax.persistence.EntityManager - JPA InterfaceInterface used to interact with the persistence context., em
, that represents a JPA connection to the object database, we can use it to store, retrieve, update and delete database objects.
Storing New Entity Objects
The following code fragment stores 1,000 Point
objects in the database:
em.getTransactionEntityManager.getTransaction() - JPA MethodReturn the resource-levelEntityTransaction
object.().beginEntityTransaction.begin() - JPA MethodStart a resource transaction.(); for (int i = 0; i < 1000; i++) { Point p = new Point(i, i); em.persistEntityManager.persist(entity) - JPA MethodMake an instance managed and persistent.(p); } em.getTransactionEntityManager.getTransaction() - JPA MethodReturn the resource-levelEntityTransaction
object.().commitEntityTransaction.commit() - JPA MethodCommit the current resource transaction, writing any unflushed changes to the database.();
Operations that modify the content of the database (such as storing new objects) require an active transaction. In the example above, every Point
object is first constructed as an ordinary Java object. It then becomes associated with an EntityManager
and with its transaction (as a managed entity) by the persist
EntityManager.persist(entity) - JPA MethodMake an instance managed and persistent. method. The new Point
objects are physically stored in the database only when the transaction is committed. The Storing Entities section in chapter 3 discusses persisting objects in the database in more detail.
JPA Queries with JPQL
We can get the number of Point
objects in the database by using a simple query:
Queryjavax.persistence.Query - JPA InterfaceInterface used to control query execution.javax.jdo.Query - JDO InterfaceTheQuery
interface allows applications to obtain persistent instances, values, and aggregate data from the data store. q1 = em.createQueryEntityManager.createQuery(qlString) - JPA MethodCreate an instance ofQuery
for executing a Java Persistence query language statement.("SELECT COUNT(p) FROM Point p"); System.out.println("Total Points: " + q1.getSingleResultQuery.getSingleResult() - JPA MethodExecute a SELECT query that returns a single untyped result.());
The query string ("SELECT COUNT(p) FROM Point p") instructs JPA to count all the Point objects in the database. If you have used SQL you should find the syntax very familiar. JPQL, the JPA query language, supports a SQL like syntax. This has a couple of significant advantages. First, you get the power of SQL combined with the ease of use of object databases and second, a new JPA developer with some experience with SQL can become productive very quickly.
The EntityManagerjavax.persistence.EntityManager - JPA InterfaceInterface used to interact with the persistence context.
object serves as the factory for Query
javax.persistence.Query - JPA InterfaceInterface used to control query execution.javax.jdo.Query - JDO InterfaceThe Query
interface allows applications to obtain persistent instances, values, and aggregate data from the data store. instances. The getSingleResult
Query.getSingleResult() - JPA MethodExecute a SELECT query that returns a single untyped result. method executes the query and returns the result. It should only be used when exactly one result value is expected (a single Long object in the query above).
Let's see another example of a query that returns a single result:
Queryjavax.persistence.Query - JPA InterfaceInterface used to control query execution.javax.jdo.Query - JDO InterfaceTheQuery
interface allows applications to obtain persistent instances, values, and aggregate data from the data store. q2 = em.createQueryEntityManager.createQuery(qlString) - JPA MethodCreate an instance ofQuery
for executing a Java Persistence query language statement.("SELECT AVG(p.x) FROM Point p"); System.out.println("Average X: " + q2.getSingleResultQuery.getSingleResult() - JPA MethodExecute a SELECT query that returns a single untyped result.());
The new query returns a Double object reflecting the average x
value of all the Point
objects in the database.
Retrieving Existing Entities
The Retrieving Entities section in chapter 3 describes several methods for retrieving entity objects from the database using JPA. Running a JPQL query is one of them:
TypedQueryjavax.persistence.TypedQuery- JPA Interface Interface used to control the execution of typed queries.<Point> query = em.createQueryEntityManager.createQuery(qlString,resultClass) - JPA MethodCreate an instance ofTypedQuery
for executing a Java Persistence query language statement.("SELECT p FROM Point p", Point.class); List<Point> results = query.getResultListTypedQuery.getResultList() - JPA MethodExecute a SELECT query and return the query results as a typed List.();
The above query retrieves all the Point
objects from the database as a list. The TypedQuery
javax.persistence.TypedQueryQuery
javax.persistence.Query - JPA InterfaceInterface used to control query execution.javax.jdo.Query - JDO InterfaceThe Query
interface allows applications to obtain persistent instances, values, and aggregate data from the data store. and is usually the preferred way to work with queries. The getResultList
TypedQuery.getResultList() - JPA MethodExecute a SELECT query and return the query results as a typed List. method executes the query and returns the result objects. It should be used (rather than getSingleResult
TypedQuery.getSingleResult() - JPA MethodExecute a SELECT query that returns a single result.) when multiple results are expected. The result list can be iterated as any ordinary Java collection.
More advanced queries, for instance, can be used to retrieve selected objects from the database (using a WHERE clause), sort the results (using an ORDER BY clause) and even group results (using GROUP BY and HAVING clauses). JPQL is a very powerful query language and chapter 4 of this manual describes it in detail.
Updating and Deleting Entities
JPA refers to entity objects that are associated with an EntityManagerjavax.persistence.EntityManager - JPA InterfaceInterface used to interact with the persistence context.
as 'managed'. A newly constructed entity object becomes managed by an EntityManager
when the persist
EntityManager.persist(entity) - JPA MethodMake an instance managed and persistent. method is invoked. Objects that are retrieved from the database are managed by the EntityManager
that was used to retrieve them (e.g. as a Query
factory).
To delete an object from the database, you need to obtain a managed object (usually by retrieval) and invoke the remove
EntityManager.remove(entity) - JPA MethodRemove the entity instance. method within the context of an active transaction:
em.getTransactionEntityManager.getTransaction() - JPA MethodReturn the resource-levelEntityTransaction
object.().beginEntityTransaction.begin() - JPA MethodStart a resource transaction.(); em.removeEntityManager.remove(entity) - JPA MethodRemove the entity instance.(p); // delete entity em.getTransactionEntityManager.getTransaction() - JPA MethodReturn the resource-levelEntityTransaction
object.().commitEntityTransaction.commit() - JPA MethodCommit the current resource transaction, writing any unflushed changes to the database.();
In the above code, p must be a managed entity object of the EntityManager
em
. The entity object is marked for deletion by the remove
method and is physically deleted from the database when the transaction is committed.
Updating an existing database object is similar. You have to obtain a managed entity object (e.g. by retrieval) and modify it within an active transaction:
em.getTransactionEntityManager.getTransaction() - JPA MethodReturn the resource-levelEntityTransaction
object.().beginEntityTransaction.begin() - JPA MethodStart a resource transaction.(); p.setX(p.getX() + 100); // update entity em.getTransactionEntityManager.getTransaction() - JPA MethodReturn the resource-levelEntityTransaction
object.().commitEntityTransaction.commit() - JPA MethodCommit the current resource transaction, writing any unflushed changes to the database.();
You may notice that em
, the managing EntityManager of p
, is not mentioned explicitly when p
is being updated. The EntityManager
that manages an entity is responsible for automatically detecting changes to the entity object and applying them to the database when the transaction is committed.
The following code demonstrates processing of all the Point
objects in the database:
TypedQueryjavax.persistence.TypedQuery- JPA Interface Interface used to control the execution of typed queries.<Point> query = em.createQueryEntityManager.createQuery(qlString,resultClass) - JPA MethodCreate an instance ofTypedQuery
for executing a Java Persistence query language statement.("SELECT p FROM Point p", Point.class); List<Point> results = query.getResultListTypedQuery.getResultList() - JPA MethodExecute a SELECT query and return the query results as a typed List.(); em.getTransactionEntityManager.getTransaction() - JPA MethodReturn the resource-levelEntityTransaction
object.().beginEntityTransaction.begin() - JPA MethodStart a resource transaction.(); for (Point p : results) { if (p.getX() >= 100) { em.removeEntityManager.remove(entity) - JPA MethodRemove the entity instance.(p); // delete entity } else { p.setX(p.getX() + 100); // update entity } } em.getTransactionEntityManager.getTransaction() - JPA MethodReturn the resource-levelEntityTransaction
object.().commitEntityTransaction.commit() - JPA MethodCommit the current resource transaction, writing any unflushed changes to the database.();
In the above example all the Point
objects whose x
coordinate is greater or equal to 100
are deleted. All the other Point
objects are updated.
Chapter 3 of this manual describes how to use JPA for database operations in more detail.