CRUD Database Operations with JPA
Given an EntityManagerjakarta.persistence.EntityManagerInterface used to interact with the persistence context. instance, em, which manages the persistence context for the database, you can use it to store, retrieve, update, and delete objects.
Storing new entities
The following code fragment stores 1,000 Point objects in the database:
em.getTransactionjakarta.persistence.EntityManager.getTransaction()Return the resource-level EntityTransaction object.().beginjakarta.persistence.EntityTransaction.begin()Start a resource transaction.(); for (int i = 0; i < 1000; i++) { Point p = new Point(i, i); em.persistjakarta.persistence.EntityManager.persist(Object)Make a new entity instance managed and persistent, resulting in its insertion in the database when the persistence context is synchronized with the database, or make a removed entity managed, undoing the effect of a previous call to EntityManager.remove .(p); } em.getTransactionjakarta.persistence.EntityManager.getTransaction()Return the resource-level EntityTransaction object.().commitjakarta.persistence.EntityTransaction.commit()Commit the current resource transaction, writing any unflushed changes to the database.();
Operations that modify the database content, such as storing new objects, require an active transaction. In the preceding example, each Point object is first constructed as a standard Java object. The persistjakarta.persistence.EntityManager.persist(Object)Make a new entity instance managed and persistent, resulting in its insertion in the database when the persistence context is synchronized with the database, or make a removed entity managed, undoing the effect of a previous call to EntityManager.remove . method then associates the object with the EntityManager and its transaction, making it a managed entity. The new Point objects are 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
You can get the number of Point objects in the database by using a simple query:
Queryjakarta.persistence.QueryInterface used to control query execution. q1 = em.createQueryjakarta.persistence.EntityManager.createQuery(String)Create an instance of Query for executing a Jakarta Persistence query language statement.("SELECT COUNT(p) FROM Point p"); System.out.println("Total Points: " + q1.getSingleResultjakarta.persistence.Query.getSingleResult()Execute a SELECT query that returns a single untyped result.());
The query string "SELECT COUNT(p) FROM Point p" instructs JPA to count all 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 approach has two significant advantages. First, it combines the power of SQL with the ease of use of object databases. Second, a new JPA developer with SQL experience can become productive very quickly.
The EntityManagerjakarta.persistence.EntityManagerInterface used to interact with the persistence context. object serves as the factory for Queryjakarta.persistence.QueryInterface used to control query execution. instances. The getSingleResultjakarta.persistence.Query.getSingleResult()Execute 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 preceding query).
The following example shows another query that returns a single result:
Queryjakarta.persistence.QueryInterface used to control query execution. q2 = em.createQueryjakarta.persistence.EntityManager.createQuery(String)Create an instance of Query for executing a Jakarta Persistence query language statement.("SELECT AVG(p.x) FROM Point p"); System.out.println("Average X: " + q2.getSingleResultjakarta.persistence.Query.getSingleResult()Execute a SELECT query that returns a single untyped result.());
This query returns a Double object that represents 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 entities from the database by using JPA. Running a JPQL query is one of them:
TypedQueryjakarta.persistence.TypedQueryInterface used to control the execution of typed queries.<Point> query = em.createQueryjakarta.persistence.EntityManager.createQuery(String,Class)Create an instance of TypedQuery<X> for executing a Jakarta Persistence query language statement.("SELECT p FROM Point p", Point.class); List<Point> results = query.getResultListjakarta.persistence.TypedQuery.getResultList()Execute a SELECT query and return the query results as a typed List<X> .();
The preceding query retrieves all the Point objects from the database as a list. The TypedQueryjakarta.persistence.TypedQueryInterface used to control the execution of typed queries. interface, which was introduced in JPA, is a type-safe subinterface of Queryjakarta.persistence.QueryInterface used to control query execution. and is usually the preferred way to work with queries. The getResultListjakarta.persistence.TypedQuery.getResultList()Execute a SELECT query and return the query results as a typed List<X> . method executes the query and returns the result objects. It should be used (rather than getSingleResultjakarta.persistence.TypedQuery.getSingleResult()Execute a SELECT query that returns a single result.) when multiple results are expected. You can iterate over the result list like any standard 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 entities that are associated with an EntityManagerjakarta.persistence.EntityManagerInterface used to interact with the persistence context. as "managed." A newly constructed entity becomes managed by an EntityManager when the persistjakarta.persistence.EntityManager.persist(Object)Make a new entity instance managed and persistent, resulting in its insertion in the database when the persistence context is synchronized with the database, or make a removed entity managed, undoing the effect of a previous call to EntityManager.remove . method is invoked. Objects that are retrieved from the database are managed by the EntityManager that was used to retrieve them (for example, as a Query factory).
To delete an object from the database, you need to obtain a managed object (usually by retrieval) and invoke the removejakarta.persistence.EntityManager.remove(Object)Mark a managed entity instance as removed, resulting in its deletion from the database when the persistence context is synchronized with the database. method within the context of an active transaction:
em.getTransactionjakarta.persistence.EntityManager.getTransaction()Return the resource-level EntityTransaction object.().beginjakarta.persistence.EntityTransaction.begin()Start a resource transaction.(); em.removejakarta.persistence.EntityManager.remove(Object)Mark a managed entity instance as removed, resulting in its deletion from the database when the persistence context is synchronized with the database.(p); // delete entity em.getTransactionjakarta.persistence.EntityManager.getTransaction()Return the resource-level EntityTransaction object.().commitjakarta.persistence.EntityTransaction.commit()Commit the current resource transaction, writing any unflushed changes to the database.();
In the preceding code, p must be a managed entity of the EntityManager instance, em. The entity is marked for deletion by the remove method and is deleted from the database when the transaction is committed.
Updating an existing database object is similar. You have to obtain a managed entity (for example, by retrieval) and modify it within an active transaction:
em.getTransactionjakarta.persistence.EntityManager.getTransaction()Return the resource-level EntityTransaction object.().beginjakarta.persistence.EntityTransaction.begin()Start a resource transaction.(); p.setX(p.getX() + 100); // update entity em.getTransactionjakarta.persistence.EntityManager.getTransaction()Return the resource-level EntityTransaction object.().commitjakarta.persistence.EntityTransaction.commit()Commit 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 updated. The EntityManager that manages an entity is responsible for automatically detecting changes to the entity and applying them to the database when the transaction is committed.
The following code demonstrates processing all the Point objects in the database:
TypedQueryjakarta.persistence.TypedQueryInterface used to control the execution of typed queries.<Point> query = em.createQueryjakarta.persistence.EntityManager.createQuery(String,Class)Create an instance of TypedQuery<X> for executing a Jakarta Persistence query language statement.("SELECT p FROM Point p", Point.class); List<Point> results = query.getResultListjakarta.persistence.TypedQuery.getResultList()Execute a SELECT query and return the query results as a typed List<X> .(); em.getTransactionjakarta.persistence.EntityManager.getTransaction()Return the resource-level EntityTransaction object.().beginjakarta.persistence.EntityTransaction.begin()Start a resource transaction.(); for (Point p : results) { if (p.getX() >= 100) { em.removejakarta.persistence.EntityManager.remove(Object)Mark a managed entity instance as removed, resulting in its deletion from the database when the persistence context is synchronized with the database.(p); // delete entity } else { p.setX(p.getX() + 100); // update entity } } em.getTransactionjakarta.persistence.EntityManager.getTransaction()Return the resource-level EntityTransaction object.().commitjakarta.persistence.EntityTransaction.commit()Commit the current resource transaction, writing any unflushed changes to the database.();
In the preceding example, all the Point objects whose x coordinate is greater than or equal to 100 are deleted. All other Point objects are updated.
Chapter 3 of this manual describes how to use JPA for database operations in more detail.