ObjectDB ObjectDB

CRUD Database Operations with JPA

Given an EntityManagerjavax.persistence.EntityManagerJPA interfaceInterface used to interact with the persistence context.See JavaDoc Reference Page..., 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.getTransactiongetTransaction()EntityManager's methodReturn the resource-level EntityTransaction object.See JavaDoc Reference Page...().beginbegin()EntityTransaction's methodStart a resource transaction.See JavaDoc Reference Page...();
  for (int i = 0; i < 1000; i++) {
      Point p = new Point(i, i);
      em.persistpersist(entity)EntityManager's methodMake an instance managed and persistent.See JavaDoc Reference Page...(p);
  }
  em.getTransactiongetTransaction()EntityManager's methodReturn the resource-level EntityTransaction object.See JavaDoc Reference Page...().commitcommit()EntityTransaction's methodCommit the current resource transaction, writing any 
 unflushed changes to the database.See JavaDoc Reference Page...();

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 persistpersist(entity)EntityManager's methodMake an instance managed and persistent.See JavaDoc Reference Page... 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.QueryJPA interfaceInterface used to control query execution.See JavaDoc Reference Page... q1 = em.createQuerycreateQuery(qlString)EntityManager's methodCreate an instance of Query for executing a
 Java Persistence query language statement.See JavaDoc Reference Page...("SELECT COUNT(p) FROM Point p");
  System.out.println("Total Points: " + q1.getSingleResultgetSingleResult()Query's methodExecute a SELECT query that returns a single untyped result.See JavaDoc Reference Page...());

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.EntityManagerJPA interfaceInterface used to interact with the persistence context.See JavaDoc Reference Page... object serves as the factory for Queryjavax.persistence.QueryJPA interfaceInterface used to control query execution.See JavaDoc Reference Page... instances. The getSingleResultgetSingleResult()Query's methodExecute a SELECT query that returns a single untyped result.See JavaDoc Reference Page... 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.QueryJPA interfaceInterface used to control query execution.See JavaDoc Reference Page... q2 = em.createQuerycreateQuery(qlString)EntityManager's methodCreate an instance of Query for executing a
 Java Persistence query language statement.See JavaDoc Reference Page...("SELECT AVG(p.x) FROM Point p");
  System.out.println("Average X: " + q2.getSingleResultgetSingleResult()Query's methodExecute a SELECT query that returns a single untyped result.See JavaDoc Reference Page...());

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.TypedQueryJPA interfaceInterface used to control the execution of typed queries.See JavaDoc Reference Page...<Point> query =
    em.createQuerycreateQuery(qlString, resultClass)EntityManager's methodCreate an instance of TypedQuery for executing a
 Java Persistence query language statement.See JavaDoc Reference Page...("SELECT p FROM Point p", Point.class);
  List<Point> results = query.getResultListgetResultList()TypedQuery's methodExecute a SELECT query and return the query results
 as a typed List.See JavaDoc Reference Page...();

The above query retrieves all the Point objects from the database as a list. The TypedQueryjavax.persistence.TypedQueryJPA interfaceInterface used to control the execution of typed queries.See JavaDoc Reference Page... interface, which was introduced in JPA 2, is a type safe subinterface of Queryjavax.persistence.QueryJPA interfaceInterface used to control query execution.See JavaDoc Reference Page... and is usually the preferred way to work with queries. The getResultListgetResultList()TypedQuery's methodExecute a SELECT query and return the query results as a typed List.See JavaDoc Reference Page... method executes the query and returns the result objects. It should be used (rather than getSingleResultgetSingleResult()TypedQuery's methodExecute a SELECT query that returns a single result.See JavaDoc Reference Page...) 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.EntityManagerJPA interfaceInterface used to interact with the persistence context.See JavaDoc Reference Page... as 'managed'. A newly constructed entity object becomes managed by an EntityManager when the persistpersist(entity)EntityManager's methodMake an instance managed and persistent.See JavaDoc Reference Page... 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 removeremove(entity)EntityManager's methodRemove the entity instance.See JavaDoc Reference Page... method within the context of an active transaction:

  em.getTransactiongetTransaction()EntityManager's methodReturn the resource-level EntityTransaction object.See JavaDoc Reference Page...().beginbegin()EntityTransaction's methodStart a resource transaction.See JavaDoc Reference Page...();
  em.removeremove(entity)EntityManager's methodRemove the entity instance.See JavaDoc Reference Page...(p); // delete entity
  em.getTransactiongetTransaction()EntityManager's methodReturn the resource-level EntityTransaction object.See JavaDoc Reference Page...().commitcommit()EntityTransaction's methodCommit the current resource transaction, writing any 
 unflushed changes to the database.See JavaDoc Reference Page...();

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.getTransactiongetTransaction()EntityManager's methodReturn the resource-level EntityTransaction object.See JavaDoc Reference Page...().beginbegin()EntityTransaction's methodStart a resource transaction.See JavaDoc Reference Page...();
  p.setX(p.getX() + 100); // update entity
  em.getTransactiongetTransaction()EntityManager's methodReturn the resource-level EntityTransaction object.See JavaDoc Reference Page...().commitcommit()EntityTransaction's methodCommit the current resource transaction, writing any 
 unflushed changes to the database.See JavaDoc Reference Page...();

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.TypedQueryJPA interfaceInterface used to control the execution of typed queries.See JavaDoc Reference Page...<Point> query =
    em.createQuerycreateQuery(qlString, resultClass)EntityManager's methodCreate an instance of TypedQuery for executing a
 Java Persistence query language statement.See JavaDoc Reference Page...("SELECT p FROM Point p", Point.class);
  List<Point> results = query.getResultListgetResultList()TypedQuery's methodExecute a SELECT query and return the query results
 as a typed List.See JavaDoc Reference Page...();

  em.getTransactiongetTransaction()EntityManager's methodReturn the resource-level EntityTransaction object.See JavaDoc Reference Page...().beginbegin()EntityTransaction's methodStart a resource transaction.See JavaDoc Reference Page...();
  for (Point p : results) {
      if (p.getX() >= 100) {
          em.removeremove(entity)EntityManager's methodRemove the entity instance.See JavaDoc Reference Page...(p); // delete entity
      }
      else {
          p.setX(p.getX() + 100); // update entity
      }
  }
  em.getTransactiongetTransaction()EntityManager's methodReturn the resource-level EntityTransaction object.See JavaDoc Reference Page...().commitcommit()EntityTransaction's methodCommit the current resource transaction, writing any 
 unflushed changes to the database.See JavaDoc Reference Page...();

In the above example all the Pointobjects whose x coordinate is greater or equal to 100 are deleted. All the other Pointobjects are updated.

Chapter 3 of this manual describes how to use JPA for database operations in more detail.