Skip to content

The specification in Jakarta EE to help Jakarta EE developers create enterprise-grade applications using Java® and NoSQL technologies.

License

Notifications You must be signed in to change notification settings

jakartaee/nosql

Jakarta NoSQL

Jakarta NoSQL logo

Introduction

Jakarta NoSQL is a comprehensive framework designed to simplify the integration of Java applications with various NoSQL databases. By providing a unified API and a set of powerful annotations, Jakarta NoSQL enables developers to seamlessly work with different NoSQL data stores while maintaining flexibility and productivity.

Goals

  • Increase productivity performing common NoSQL operations.

  • Rich Object Mapping integrated.

  • Java-based Query and Fluent-API.

  • It is designed to work with various NoSQL databases and can quickly adapt to support new types and behaviors through extensions.

  • Annotation-oriented using Jakarta Persistence-like naming when it makes sense.

One Mapping API to Multiples NoSQL Databases

Jakarta NoSQL provides one API for each NoSQL database type. However, it incorporates the same annotations from the Jakarta Persistence specification and heritage Java Persistence Architecture (JPA) to map Java objects. Therefore, with just these annotations that look like Jakarta Persistence, there is support for more than twenty NoSQL databases.

@Entity
public class Car {

    @Id
    private Long id;
    @Column
    private String name;
    @Column
    private CarType type;
 //...
}

Annotations

The annotations from the Mapping API will look familiar to Jakarta Persistence developers:

Annotation

Description

@Entity

Specifies that the class is an entity. This annotation is applied to the entity class.

@Id

Specifies the primary key of an entity.

@Column

Specifies the mapped column for a persistent property or field.

@MappedSuperclass

Specifies a class whose mapping information is applied to entities that inherit from it.

@Embeddable

Declares a class whose instances are stored as an intrinsic part of an owning entity, sharing the identity of the entity.

@Inheritance

Specifies the inheritance mapping strategy for the entity class hierarchy.

@DiscriminatorColumn

Specifies the discriminator column for the mapping strategy.

@DiscriminatorValue

Specifies the value of the discriminator column for the annotated entity type.

@Convert

Specifies how the values of a field or property are converted to a basic type or a type that can be persisted by a persistence provider.

These annotations serve as a familiar and powerful toolkit for Java developers, enabling them to map Java objects to NoSQL databases similarly to how Jakarta Persistence works with relational data.

Template

The Template interface is the central entry point for interacting with a NoSQL database in Jakarta NoSQL. It provides a consistent, high-level API for performing common persistence operations such as insert, update, delete, and query.

Jakarta NoSQL supports multiple interaction styles through the Template, including:

  • Basic CRUD operations

  • Fluent-style query builders

  • String-based queries with support for projections

Basic Operations

Once you’ve annotated your entity, you can perform basic operations like insert, find, and delete using the Template instance.

@Inject
Template template;

Car ferrari = Car.builder()
        .id(1L)
        .name("Ferrari")
        .type(CarType.SPORT)
        .build();

template.insert(ferrari);

Optional<Car> car = template.find(Car.class, 1L);

template.delete(Car.class, 1L);

Jakarta NoSQL provides a unified API with specialized support for a wide range of NoSQL databases, including but not limited to document, key-value, column-oriented, graph, and emerging models.

Fluent API

Jakarta NoSQL provides a fluent API for dynamic query construction, enabling you to perform more expressive filtering and deletion operations programmatically — without writing string-based queries.

Select example:

List<Car> sportsCars = template.select(Car.class)
    .where("type").eq(CarType.SPORT)
    .orderBy("name")
    .result();

Delete example:

template.delete(Car.class)
    .where("type").eq(CarType.CLASSIC)
    .execute();

This style promotes type safety and cleaner code, especially in dynamic or reusable query scenarios.

Typed Queries and Projections

Jakarta NoSQL supports string-based queries using the Jakarta Query Core language. There are two main methods for executing these queries:

  • query(String) — executes a generic query that always returns entities and requires an explicit FROM clause.

  • typedQuery(String, Class<T>) — maps results to either an entity or a projection class. Supports omitting the FROM clause when used with @Projection(from = …​).

Using query(String) – entity results only

The query(String) method is useful for selecting full entity instances, deleting, or updating data. It always returns entity types and requires a FROM clause in the query.

List<Car> cars = template.query("FROM Car WHERE type = :type")
                         .bind("type", CarType.SPORT)
                         .result();

Optional<Car> one = template.query("FROM Car WHERE id = :id")
                            .bind("id", 42)
                            .singleResult();
Important
You cannot use projections with query(String) — only entity classes are supported.
Using typedQuery(String, Class<T>) – entities and projections

Use typedQuery(…​) when you want to:

  • Retrieve data as a projection (using record and @Projection)

  • Omit the FROM clause when using @Projection(from = …​)

This method supports the full query API — result(), stream(), and singleResult():

@Projection
public record TechCarView(String name, CarType type) {}

List<TechCarView> cars = template
    .typedQuery("FROM Car WHERE type = 'SPORT'", TechCarView.class)
    .result();

You may also omit the FROM clause entirely if you annotate the projection with @Projection(from = Car.class):

@Projection(from = Car.class)
public record BudgetCar(String name, double price) {}

List<BudgetCar> cheapCars = template
    .typedQuery("WHERE price < 100", BudgetCar.class)
    .result();
Single result queries

Both query(…​) and typedQuery(…​) support retrieving a single result wrapped in an Optional:

Optional<Car> car = template.query("FROM Car WHERE id = :id")
                            .bind("id", "c-001")
                            .singleResult();

Optional<BudgetCar> result = template
    .typedQuery("WHERE price < 100", BudgetCar.class)
    .singleResult();

Maven dependency

<dependency>
    <groupId>jakarta.nosql</groupId>
    <artifactId>jakarta.nosql-api</artifactId>
    <version>1.0.1</version>
</dependency>

More Information

To learn more, please refer to the reference documentation, and JavaDocs.

Code of Conduct

This project is governed by the Eclipse Foundation of Conduct. By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to codeofconduct@eclipse.org.

Getting Help

Having trouble with Jakarta NoSQL? We’d love to help!

Please report any bugs, concerns or questions with Jakarta NoSQL to https://github.com/jakartaee/nosql.

Building from Source

You don’t need to build from source to use the project, but should you be interested in doing so, you can build it using Maven and Java 21 or higher.

mvn clean install

About

The specification in Jakarta EE to help Jakarta EE developers create enterprise-grade applications using Java® and NoSQL technologies.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

No packages published

Contributors 16

Languages