Spring JPA Dynamic Query (JDQ)
Production-ready DTO to JPA-Specification converter with multi-join support, published as Maven library
Spring JPA Dynamic Query (JDQ)
A production-ready library that simplifies the JPA Criteria API, enabling programmatic and dynamic runtime query creation. Published as a Maven artifact with 10k+ downloads.
Features
- 9 field operators — EQUAL, NOT_EQUAL, CONTAIN, DOES_NOT_CONTAIN, START_WITH, END_WITH, GREATER_THAN, LESS_THAN, SPECIFIED (null check)
- AND-OR conjunctions — Complex boolean logic with
Criteria.OR() - SCOPE support — Nested parentheses for complex queries:
(A OR B) AND (C OR D) - Single or multi JOIN — Automatic JOIN generation via dot notation (
department.name) - Projection support — Select specific fields with alias mapping and nested object mapping
- Pagination — Page-based results with
Page<T>support - ORDER BY — Sort by any field, including joined columns
- DISTINCT — Distinct result filtering
- Query Builder — Fluent API for programmatic query construction
- Argument Resolver — Auto-convert request parameters to DynamicQuery objects
Quick Start
Maven Dependency
<!-- Spring Boot 3.x -->
<dependency>
<groupId>io.github.tdilber</groupId>
<artifactId>spring-boot-starter-jpa-dynamic-query</artifactId>
<version>0.3.0</version>
</dependency>
<!-- Spring Boot 2.x -->
<dependency>
<groupId>io.github.tdilber</groupId>
<artifactId>spring-jpa-dynamic-query</artifactId>
<version>0.6.0</version>
</dependency>
Enable Annotation
@EnableJpaDynamicQuery
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
Create Repository
public interface UserRepository extends JpaDynamicQueryRepository<User, Long> {
// No implementation needed — all methods inherited
}
Execute Queries
// Simple WHERE clause
List<User> activeUsers = userRepository.findAll(
CriteriaList.of(
Criteria.of("status", CriteriaOperator.EQUAL, "ACTIVE"),
Criteria.of("age", CriteriaOperator.GREATER_THAN, 25)
)
);
// With JOIN
List<User> result = userRepository.findAll(
CriteriaList.of(
Criteria.of("department.name", CriteriaOperator.START_WITH, "Engineering")
)
);
// With projection
List<UserSummary> summaries = userRepository.findAll(
dynamicQuery,
UserSummary.class
);
Query Builder Example
Page<UserSummary> result = userRepository.queryBuilder()
.select(Select("id", "userId"), Select("name", "userName"))
.where(
Field("status").eq("ACTIVE"),
Field("age").gte(25)
)
.orderBy(OrderBy("name", Order.ASC))
.page(0, 20)
.getResultAsPage(UserSummary.class);
REST API Example
# Query with dynamic parameters
curl "http://localhost:8080/users?select0=id&select1=name&where0_key=status&where0_operation=EQUAL&where0_values0=ACTIVE&page=0&size=20"
Comparison with Traditional JPA
| Feature | Traditional JPA | JDQ |
|---------|----------------|-----|
| Dynamic WHERE | Manual Criteria API | Criteria.of() |
| JOIN handling | Explicit @Join annotations | Dot notation field.name |
| Multi-table JOIN | Complex path expressions | Automatic via annotations |
| Projection | @Query with DTO | Automatic with @JdqModel |
| OR logic | Specification.or() | Criteria.OR() |
| SCOPE/Nesting | Manual conjunction() | CriteriaOperator.PARENTHES |
Production Usage
- Downloaded 10k+ times via Maven Central
- Used in production at multiple enterprises
- 0.3.0 — Current stable version (Spring Boot 3.x)
- 0.6.0 — Latest for Spring Boot 2.x
Resources
- Demo App: spring-jpa-dynamic-query-presentation-demo
- Live Demo: tdilber.com/dynamic-query-demo
- YouTube Tutorial: Turkish introduction video