PojoQuery Documentation

PojoQuery Logo

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 @Embedded

Dynamic columns

Handle schemaless patterns with @Other for dynamic column mappings

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.

— Martin Fowler

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

Building from Source

To build PojoQuery from the source code:

  1. Prerequisites: Ensure you have JDK 17 or later installed.

  2. Clone the repository:

    git clone https://github.com/martijnvogten/pojoquery.git
  3. Navigate to the project directory:

    cd pojoquery
  4. 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.