Library / SDK
babyfish-ct/jimmer avatar
babyfish-ct/jimmer

Jimmer treats a query result as a data structure, not an entity graph

The most advanced ORM of JVM, for both java & kotlin

1,672 stars158 forksJavaApache-2.0

At a glance

What is it?
Jimmer is a JVM ORM for Java and Kotlin that reads and writes arbitrary shaped data structures as a whole, with a compile-time DTO generator, graph queries without N+1 problems, and a DTO that can be incomplete at any level. The cost is a compile-time processor in your build, and the README ships no install command, pointing instead at jimmer.org.
Who is it for?
Adopt Jimmer when your team wants nested projections and partial updates on relational data without hand-writing DTO mapping, and when everyone on the project can accept an Apt or Ksp processor in the build. Do not adopt it for a project that cannot take that build dependency, or if you only need plain CRUD.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 16 days ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The unit of work is a shape, not an entity

Most Java persistence work is organised around entities: you load one, navigate its associations, mutate properties, save it back. Jimmer inverts that. Its stated core concept is reading and writing data structures of arbitrary shapes as a whole, and the README is blunt about the consequence: Jimmer entity objects are not POJOs, and that is what lets them express a data structure whose shape is decided at the call site rather than in annotations.

That has one immediate ergonomic effect. There is no need to plan the object graph in advance, because nothing about the graph is fixed at compile time. You construct the shape the current business case needs, hand it to Jimmer, and get it back.

The comparison table in the README draws the line against three familiar technologies. GraphQL reaches clients over HTTP while Jimmer offers the same shape of query as a local framework API call. JPA needs insertable, updatable and cascade configuration to fix the shape of what gets saved. MongoDB leaves every document a data island whose internal hierarchy has to be agreed on before any query runs.

A paginated query gets its count query generated and optimised

The query side is where the SQL work happens. The DSL supports mixing native SQL expressions into a query, which is how database specific capabilities get used without leaving the typed builder, and it covers derived tables, CTEs and recursive CTEs.

The optimisation list is the part a database administrator would care about. Jimmer removes unnecessary table joins, merges logically equivalent table joins, merges logically equivalent implicit subqueries, and generates plus optimises the count query that accompanies a paginated query instead of leaving that count to be hand written.

Recursive queries over self referencing properties are supported, which the README contrasts with GraphQL and with JPA's entity graph facilities. Recursion is the case that breaks most hand written graph loading code, so treat this as the feature to test first against your own schema rather than trusting the claim on faith.

DTOs are generated at compile time, not written by hand

Three kinds of DTO appear in the feature list: output DTOs for returning complex query results, input DTOs for saving complex structures, and specification DTOs for querying. All of them come from the same compile time generator.

The argument the README makes against JPA here is specific. In JPA a DTO used for partial loading has to be a flat object with no associations, which strips away the ORM capability that made it worth using and leaves a plain object mapper. Jimmer's generated DTOs support arbitrarily nested hierarchical relationships, and the README claims that no other ORM supports nested projections based on DTO.

It also generates client contracts from document comments, producing OpenAPI and TypeScript output. Jimmer has its own implementations for both, so you do not add annotations to your controllers to get either. Read that as a claim to verify on a sample project, since generated OpenAPI and TypeScript types are exactly the kind of output where mismatches with what you expect tend to hide.

Incomplete objects are legal on both the read and the write side

The consequence of not using POJOs shows up in persistence semantics. Objects at any level can be incomplete when reading, and saved objects at any level can be incomplete when writing. Compare that with JPA, where an update touches every updatable column, which is why so much JPA code reads an object fully, changes one property, and writes the whole thing back.

Writes are pushed into the database rather than assembled in memory. Merge uses the database's own upsert, multiple objects at each level are handled with batch DML, and constraint violation exceptions are translated rather than left to surface raw.

Caching is layered, with the technology for each layer chosen independently, and the README is explicit that the cache holds more than object instances: associations, computed values and multiple views are cached too, with consistency maintained automatically. That is a large claim surface. Cache coherence bugs are the classic failure mode of multi layer caches in an ORM, so this is the second area to test with real data volumes rather than a toy dataset.

The build now needs an annotation processor

There is no install command in this repository's README and this article does not invent one. The project directs readers to jimmer.org, and there is a separate documentation site linked from the logo badge.

What the README does warn about is the build model. Jimmer is a compile time framework that uses Apt and Ksp, the standard annotation processing technologies, and Java IDEs support both. In the common case where a change touches Java or Kotlin sources, such as an entity type or a web controller, you press Run or Debug once in the IDE and the generated source and resource files update without a full compile.

That is convenient and it is also a coupling. Anyone building this project with a toolchain that does not run annotation processors, or on a JVM language that lacks a working processor path, gets a project that does not build. Budget for that during evaluation rather than discovering it at integration time.

The performance claim is a picture, not a number

The README has a section titled Ultimate performance, and what sits under that heading is an image file, performance.jpg, alongside a feature.svg for the capability overview. There is no table of numbers, no methodology and no hardware description anywhere in the repository text.

The project also carries benchmark directories, benchmark/ and benchmark-internal/, which tells you benchmark work exists, though the README does not describe what is measured or how to reproduce it.

The practical reading: the performance section cannot be used to decide anything on its own. Run your own queries against your own schema and compare, and treat the repository benchmarks as a place to look for harness details rather than as a result to cite.

Licence, releases and who should look elsewhere

Jimmer is released under the Apache 2.0 license, with a NOTICE file alongside LICENSE, which is permissive for both commercial use and modification, subject to the usual notice and licence retention requirements.

Activity is current. The last push was on 2026-10-07, and v0.12.4 shipped on 2026-10-06 after v0.12.2 on 2026-09-11 and v0.12.1 on 2026-09-08. Release numbering is still pre 1.0, so the API surface should be expected to move.

It is the wrong tool in a few clear situations. If your project cannot add an annotation processor to the build, stop there. If your data access needs are plain CRUD against a small number of tables, the compile time machinery is cost without payoff. And if your team needs its persistence layer to be vendor neutral across several entity models, the deliberate non POJO entity design makes Jimmer hard to set aside later.

Editorial conclusion

Adopt Jimmer when your team wants nested projections and partial updates on relational data without hand-writing DTO mapping, and when everyone on the project can accept an Apt or Ksp processor in the build. Do not adopt it for a project that cannot take that build dependency, or if you only need plain CRUD. Verify first, on jimmer.org, the Gradle or Maven setup for your build and the DTO interfaces for your entities, since the README itself documents no installation command or configuration keys.

Frequently asked questions

How do I install Jimmer for Java or Kotlin?

The repository README gives no installation command and instead points to jimmer.org and the documentation site. What it does state is that Jimmer is a compile time framework built on Apt and Ksp, so the project you adopt it into must run an annotation processor.

How does Jimmer avoid N+1 queries when loading associations?

Jimmer is built around querying arbitrary graph structures as a whole rather than navigating entities one at a time, and objects at any level of the result can be incomplete. Recursive queries on self referencing properties are also supported.

What kinds of DTO does Jimmer generate?

Output DTOs for returning complex queries, input DTOs as parameters for complex saves, and specification DTOs for complex queries. The generated DTOs support nested hierarchical relationships rather than being flat objects.

Is Jimmer suitable for production use?

The repository is not archived and the last push was on 2026-10-07, with v0.12.4 released on 2026-10-06. Versions are still below 1.0, and the README does not make a production readiness claim.

Official sources

  1. babyfish-ct/jimmer on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/babyfish-ct-jimmer.svg)](https://hysenlabs.com/projects/babyfish-ct-jimmer)

Was this useful?