PojoQuery Documentation

What is PojoQuery?
PojoQuery is a lightweight Java library for working with relational databases that takes a different approach to Object-Relational Mapping (ORM). Instead of using Java classes as table definitions, PojoQuery uses them as query definitions that shape the result set. This simple yet powerful paradigm eliminates many common ORM problems while keeping your database access code clean and maintainable.
The PojoQuery Difference: Your Java classes define what you want to get from the database, not how data is stored, freeing you from the object-relational impedance mismatch.
Key Features
| Feature | Description |
|---|---|
Type-safe queries |
Define queries using Java POJOs with full type safety and IDE support |
Smart SQL generation |
Automatic SQL generation with optimized JOINs based on your POJO structure |
Relationship mapping |
Easily map one-to-one, one-to-many, and many-to-many relationships |
No session management |
No lazy loading, no proxies, no complex session tracking |
Complete control |
Full access to customize SQL when needed while keeping the ORM advantages |
Clean POJO model |
No need to extend base classes or implement interfaces |
Multi-database support |
Works with MySQL, PostgreSQL, HSQLDB, and most JDBC-compliant databases |
Inheritance mapping |
Support for table-per-subclass inheritance patterns |
Embedded objects |
Map complex object structures to database tables with |
Dynamic columns |
Handle schemaless patterns with |
Rationale
The main difference with conventional Object Relational Mapping (ORM) is that types (Java classes) do not double as table definitions but rather as query definitions. More precisely, the POJO defines the shape of the resultset. This implies that type definitions must be cycle-free.
This principle is the key to avoiding lazy loading and other complexities of conventional ORM. See this article about model-driven ORM.
The hardest part of building a software system is deciding what to build […], not the actual implementation difficulties.
PojoQuery allows you to focus on the data you need for each use case rather than trying to shoehorn your domain model into database tables.
Quick Example
Define your POJOs to represent the data structure you want to retrieve:
// Define the main entity, mapping to the 'article' table
@Table("article")
class Article {
@Id Long id;
String title;
String content;
User author; // Automatically joins with the 'user' table based on 'author_id'
List<Comment> comments; // Automatically joins with the 'comment' table based on 'article_id'
// Getters and setters omitted for brevity
}
// Define the related 'user' entity
@Table("user")
class User {
@Id Long id;
String firstName;
String lastName;
String email;
// Getters and setters omitted for brevity
}
// Define the related 'comment' entity
@Table("comment")
class Comment {
@Id Long id;
String comment;
Date submitdate;
User author; // Automatically joins with the 'user' table based on 'author_id'
// Getters and setters omitted for brevity
}
Build and execute the query using PojoQuery:
// Assuming 'connection' is your active JDBC Connection
List<Article> articles = PojoQuery.build(Article.class) // Start building a query for Article
.addWhere("article.id = ?", 123L) // Filter by article ID
.addOrderBy("comments.submitdate DESC") // Order comments by submission date
.execute(connection); // Execute the query against the database connection
// Process the results
for (Article article : articles) {
System.out.println("Article Title: " + article.getTitle());
System.out.println("Author: " + article.getAuthor().getFirstName());
System.out.println("Number of comments: " + article.getComments().size());
}
This generates a predictable SQL query, joining article, user (for article author), comment, and user (for comment author) tables.
When to Use PojoQuery
-
When you need to fetch complex, nested data structures with a single query
-
When you want direct control over the SQL being generated
-
When you need to create different "views" or projections of your data
-
When you want to avoid the complexity of ORM session management
-
In applications with complex read/query patterns but simple write operations
-
When performance and predictability are priorities
Getting Started
To begin using PojoQuery in your project, see our Getting Started guide.
Documentation Structure
-
Getting Started - Setup and basic usage
-
Features - Overview of PojoQuery capabilities
-
Annotations - Detailed reference for all annotations
-
Query Building - Using the fluent API to construct queries
-
Database Support - Information on supported databases and configuration
-
Advanced Topics - Inheritance, custom joins, streaming, and more
-
Examples - Practical code examples
Building from Source
To build PojoQuery from the source code:
-
Prerequisites: Ensure you have JDK 17 or later installed.
-
Clone the repository:
git clone https://github.com/martijnvogten/pojoquery.git -
Navigate to the project directory:
cd pojoquery -
Build with Maven Wrapper:
-
On Linux/macOS:
./mvnw clean install -
On Windows:
mvnw.cmd clean install
-
This will compile the code, run tests, and install the artifact into your local Maven repository.