JPA Query Structure (JPQL / Criteria)

The syntax of the Jakarta Persistence Query Language (JPQL) is similar to SQL. This is a key advantage because SQL is a powerful query language, and many developers are already familiar with it.

The main difference between SQL and JPQL is that SQL operates on relational database tables, while JPQL operates on Java classes and objects. For example, a JPQL query can retrieve entities, unlike SQL, which returns only field values from database tables. This makes JPQL more object-oriented and easier to use in Java applications.

JPQL Query Structure

Like SQL, a JPQL SELECT query consists of up to six clauses in the following format:

SELECT ... FROM ...
[WHERE ...]
[GROUP BY ... [HAVING ...]]
[ORDER BY ...]

The SELECT and FROM clauses are required in every query that retrieves data; update and delete queries have a slightly different structure. The other JPQL clauses--WHERE, GROUP BY, HAVING, and ORDER BY are optional.

The structure of JPQL DELETE and UPDATE queries is simpler:

DELETE FROM ... [WHERE ...]
UPDATE ... SET ... [WHERE ...]

With a few exceptions, JPQL is case-insensitive. For example, JPQL keywords can be uppercase (e.g., SELECT) or lowercase (e.g., select). The exceptions, where JPQL is case-sensitive, include Java source elements such as the names of entity classes and persistent fields. String literals are also case-sensitive (e.g., "ORM" and "orm" are different values).

A Minimal JPQL Query

The following query retrieves all Country objects from the database:

SELECT c FROM Country AS c

This example demonstrates a minimal JPQL query because the SELECT and FROM clauses are mandatory.

The FROM clause declares one or more query variables, also known as identification variables. Query variables are similar to loop variables in programming languages. Each query variable represents an iteration over objects in the database. A query variable that is bound to an entity class is called a range variable. Range variables define an iteration over all the database objects of a bound entity class and its descendant classes. In the query above, c is a range variable that is bound to the Country entity class and defines an iteration over all Country objects in the database.

The SELECT clause defines the query results. The query above returns every Country object from the iteration of the c range variable, which in this case includes all Country objects in the database.

Organization of this Section

This section contains the following pages:

The following list links to detailed explanations of how to build clauses for Criteria API queries: