ProjectionQuery

Summary

ProjectionQuery ↑

ProjectionQuery builds dynamic Jakarta Persistence queries and maps selected fields to Java records or DTOs. Use it directly with an EntityManager or through Spring Boot auto-configuration.

The core requires Java 17+ and a configured JPA/Hibernate environment. It does not require Spring. Result types use Java generics, while property paths are strings resolved at runtime.

The project is split into multiple modules:

Project Repository: https://github.com/juliocmbueno/jb-projects-projection-query


Installation (Maven) ↑

These examples use version 3.6.0, as declared in this repository. Configure your entity mappings, database connection, and JDBC driver before executing queries. The Spring dependency includes the core module transitively.

Without Spring

<dependency>
    <groupId>io.github.juliocmbueno</groupId>
    <artifactId>projection-core</artifactId>
    <version>3.6.0</version>
</dependency>

With Spring Boot

<dependency>
    <groupId>io.github.juliocmbueno</groupId>
    <artifactId>projection-spring-data</artifactId>
    <version>3.6.0</version>
</dependency>

Basic Usage ↑

Defining a projection

First, define the result shape for an existing Customer entity.

@Projection(of = Customer.class)
public record CustomerBasicData(
        @ProjectionField Long id,
        @ProjectionField String name,
        @ProjectionField("address.city.name") String city,
        @ProjectionField("address.city.state.name") String state
) { }

In the following examples, we assume a JPA context in which the ProjectionProcessor receives an EntityManager instance, responsible for executing the queries.

1. Example using a projection class:

ProjectionProcessor processor = new ProjectionProcessor(entityManager);
List<CustomerBasicData> customers = processor.execute(CustomerBasicData.class);

2. Example using a fully configured ProjectionQuery:

ProjectionProcessor processor = new ProjectionProcessor(entityManager);

ProjectionQuery<Customer, CustomerBasicData> query = ProjectionQuery
    .fromTo(Customer.class, CustomerBasicData.class)
    .filter("address.city.name", ProjectionFilterOperator.EQUAL, "São Paulo")
    .order("name", OrderDirection.ASC)
    .paging(0, 20)
    .distinct();

List<CustomerBasicData> customers = processor.execute(query);

3. Example using ProjectionPage result:

ProjectionProcessor processor = new ProjectionProcessor(entityManager);

ProjectionQuery<Customer, CustomerBasicData> query = ProjectionQuery
    .fromTo(Customer.class, CustomerBasicData.class)
    .paging(0, 20);

ProjectionPage<CustomerBasicData> page = processor.executePageable(query);

This is a basic introduction. More advanced topics such as specifications, complex filters, sorting, pagination, and integration with Spring Data JPA are covered in the next sections.


↑ Back to top · Next → Defining Projection Classes