Skip to content

jakartaee/query

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Jakarta Query

Jakarta Query serves as a unifying specification that provides a common object-oriented query language for the Jakarta ecosystem. It establishes a shared foundation that can be used consistently across Jakarta Persistence, Jakarta Data, and Jakarta NoSQL, ensuring that developers rely on a single query model rather than separate, independently evolving languages.

graph LR
    JP([Jakarta Persistence]):::spec -->|depends on| JQ([Jakarta Query]):::main
    JD([Jakarta Data]):::spec -->|depends on| JQ
    JN([Jakarta NoSQL]):::spec -->|depends on| JQ

    classDef main fill:#019DDC,stroke:#1D5183,stroke-width:2px,color:#fff,font-weight:bold
    classDef spec fill:#F8F7F7,stroke:#1D5183,stroke-width:1px,color:#1D5183
Loading

To accommodate the diversity of datastores in the Jakarta ecosystem, Jakarta Query distinguishes between two levels of the language: a core subset, designed for use by Jakarta Data and Jakarta NoSQL providers targeting non-relational databases, and an extended form, tailored for Jakarta Persistence and other providers working with relational technologies.

  • a core language that can be implemented by Jakarta Data and Jakarta NoSQL providers using non-relational datastores, and
  • an extended language tailored for Jakarta Persistence providers or other persistence technologies backed by relational databases.

⚠️ Note
While Jakarta Data primarily targets the Core language, it may also support
the Extended language if its implementation is based on Jakarta Persistence.

The language is closely based on the existing query languages defined by Jakarta Persistence and Jakarta Data, and is backward compatible with both.

graph TB
    JQ([Jakarta Query]):::main

    subgraph Extended["Extended Language"]
        Core((Core Language)):::core
    end

    Core --> JD[Jakarta Data]:::spec
    Core --> JN[Jakarta NoSQL]:::spec
    Extended --> JP[Jakarta Persistence]:::spec

    JQ --> Extended

    classDef main fill:#019DDC,stroke:#1D5183,stroke-width:2px,color:#fff,font-weight:bold
    classDef core fill:#F8F7F7,stroke:#1D5183,stroke-width:2px,color:#1D5183
    classDef spec fill:#ffffff,stroke:#999,stroke-width:1px,color:#1D5183
Loading

Jakarta Query prioritizes clients written in Java. However, it is not by nature limited to Java, and implementations in other sufficiently Java-like programming languages are encouraged.

Object-oriented query languages

A data structure in an object-oriented language is a graph of objects interconnected by unidirectional object references, which may be polymorphic. Some non-relational databases support similar representations. On the other hand, relational databases represent relationships between entities using foreign keys, and therefore SQL has no syntactic construct representing navigation of an association. Similarly, inheritance and polymorphism can be easily represented within the relational model, but are not present as first-class constructs in the SQL language. An object-oriented query language is a dialect of SQL with support for associations and subtype polymorphism.

Historical background

Object-oriented dialects of SQL have existed since at least the early 90s. The Object Query Language (OQL) was an early example, targeting object databases, but was never widely used, since object databases were themselves not widely adopted. Hibernate Query Language (HQL) and the Enterprise JavaBeans Query Language (EJB-QL) were both introduced in 2001 as query languages intended for use with object/relational mapping. HQL was widely adopted by the Java community and was eventually standardized as the Java Persistence Query Language (JPQL) by JSR-220 in 2006. JPQL has been implemented by at least five different products and is in extremely wide use today. On the other hand, since JPQL is defined as part of the Jakarta Persistence specification, it has not been reused outside the context of object/relational mapping in Java. More recently, Jakarta Data 1.0 introduced the Jakarta Data Query Language (JDQL), a strict subset of JPQL intended for use with non-relational databases. It is now inconvenient that JDQL and JPQL are maintained separately by different groups, and so the Jakarta Query project has taken on responsibility for their evolution.

timeline
  title Evolution of Object-Oriented Query Languages in Java
  1990s : OQL introduced for object databases (never widely adopted)
  2001  : HQL (Hibernate Query Language) and EJB-QL introduced
  2006  : JPQL standardized in JSR-220 (Jakarta Persistence)
  2023  : JDQL released with Jakarta Data 1.0 for non-relational databases
  2025  : Jakarta Query unifies JPQL and JDQL into one specification
Loading

Language Levels in Jakarta Query

Core Language

The Core language is a subset of the full Jakarta Query language, focusing on portable operations such as selection, restriction, ordering, and simple projection. To illustrate, consider the following JSON representation of a Room document:

{
  "id": "R-101",
  "type": "DELUXE",
  "status": "AVAILABLE",
  "number": 42
}

Using the Core language, a query might retrieve all deluxe rooms that are available, ordered by their number:

from Room where type = 'DELUXE' and status = 'AVAILABLE' order by number

Extended Language

The Extended language is the full query language defined by the Jakarta Query specification. It introduces SQL-oriented constructs such as joins, grouping, and bulk updates or deletes, which are especially useful in relational contexts. For example, imagine a Hotel document with an embedded list of rooms:

{
  "id": "H-200",
  "name": "Grand Hotel",
  "rooms": [
    { "id": "R-101", "status": "OCCUPIED" },
    { "id": "R-102", "status": "OCCUPIED" },
    { "id": "R-103", "status": "AVAILABLE" }
  ]
}

With the Extended language, a query could count the number of occupied rooms per hotel, returning only those with more than ten:

select h.name, count(r)
from Hotel h join h.rooms r
where r.status = 'OCCUPIED'
group by h.name
having count(r) > 10
order by count(r) desc

Language Levels and Feature Summary

The Core and Full grammars together define two levels of Jakarta Query: Core and Extended.
The Core level represents the minimal, portable subset, while the Extended level is a superset that introduces SQL-oriented features such as joins, grouping, and subqueries.
This subsection summarizes the differences between them, based on the syntax defined in the [Core language grammar] and the [Full language grammar] sections.

Note
In the following tables:

  • Yes = Feature available at this level
  • No = Feature not available at this level

Clauses and Constructs

Feature / Construct Core Extended
FROM clause Yes Yes
WHERE clause Yes Yes
ORDER BY clause Yes Yes
SELECT paths/id/count Yes Yes
Update (UPDATE ... SET) Yes Yes
Delete (DELETE FROM) Yes Yes
Joins (inner/left/fetch) No Yes
Grouping (GROUP BY) No Yes
Having (HAVING) No Yes
Aggregate functions (SUM, AVG, MIN, MAX) No Yes
Distinct in SELECT No Yes
Constructor expressions No Yes
Subqueries (EXISTS, IN, ALL, ANY, SOME) No Yes
Set operations (UNION, INTERSECT, EXCEPT) No Yes

Special Expressions and Functions

Datetime Expressions
Expression Core Extended
LOCAL DATE, LOCAL TIME, LOCAL TIMESTAMP Yes Yes
EXTRACT(field FROM x) No Yes
Boolean Expressions
Expression Core Extended
Literals TRUE, FALSE Yes Yes
EXISTS No Yes
Numeric Expressions
Expression Core Extended
Basic operators (+, -, *, /) Yes Yes
ABS Yes Yes
MOD No Yes
ROUND No Yes
String Expressions
Expression Core Extended
|| concatenation Yes Yes
LENGTH Yes Yes
LOWER, UPPER Yes Yes
LEFT, RIGHT Yes Yes
LOCATE No Yes
SUBSTRING No Yes

About

Jakarta Query

Resources

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages