Back to browse
GitHub Repository

A thin wrapper around JPA's EntityManager API with first-class fetch control

0 starsJava

Jpa-fetch – JPA fetch control that doesn't suck

by alexlitovsky·Mar 5, 2026·1 point·0 comments

AI Analysis

●●SolidSolve My ProblemBig Brain

EntityGraph finally doesn't suck, but QueryDSL/Hibernate already solve N+1 deeply.

Strengths
  • Type-safe path expressions catch fetch mismatches at compile time, eliminating string brittleness that haunts raw EntityGraph API
  • QueryDSL and JPA metamodel dual APIs let teams pick their existing toolchain without learning new syntax
  • Minimal wrapper keeps zero-dependency option while offering compose-friendly alternative to verbose subgraph chains
Weaknesses
  • N+1 query problems are already solved by Hibernate hints, QueryDSL, and JOOQ—this reframes the ergonomics, not the fundamental constraint
  • Niche audience (JPA users still wrestling with EntityGraph) limits impact; most serious shops moved past vanilla JPA years ago
Target Audience

Backend developers using Spring/JPA stack

Similar To

Hibernate · QueryDSL · JOOQ

Post Description

Fetch control in JPA has always been a mess. Eager loading kills performance the moment your object graph gets non-trivial. Lazy loading hands you N+1 problems and `LazyInitializationException` as a reward for doing the right thing.

Most serious projects I've seen land in one of two places: lazy + proliferation of nearly-identical queries that differ only in what they fetch, or they give up on mapping relationships altogether and treat their relational DB like a document DB. The others either have these performance issues, or don't yet know that they have them.

`EntityGraph` looked like it was finally going to fix this. Call-site fetch control, no more one-size-fits-all fetch strategies — great idea. But the API they gave us sucks. If you've ever tried to use it, you know what I mean. In fact, I've yet to see any actual uses of it in real production apps.

So I built the API I wish the spec had given us. Since we can't change the spec, this was the next best thing — it extends and mimics the `EntityManager` API, but makes fetch control a first-class concern rather than an afterthought bolted on via `EntityGraph`. You express fetch paths as generated QueryDSL path varargs — compile-time checked, refactor-safe, and composable:

entityFinder.find(Person.class, id, QPerson.person.organization().country(), QPerson.person.role());

It also works with JPA metamodel attributes, but that API is clunkier because the metamodel spec never gave us composable paths like QueryDSL did.

Person person = entityFinder.find(Person.class, id, FetchPaths.of(Person_.organization, Organization_.country), FetchPaths.of(Person_.role));

The library builds and merges the `EntityGraph` for you at runtime. Same idea works for inline JPQL and named queries via a fluent `TypedQuery`-compatible API.

https://github.com/alterioncorp/jpa-fetch

I've been using this concept in various forms in production since EntityGraphs were first introduced. Finally decided to clean it up and put it out there. Maybe others find it useful.

Similar Projects

Open Source●●Solid

AudioNimbus – Safe Rust Wrapper for Steam Audio

The project solves the usual pain of linking a C audio SDK by offering an auto-download/link feature and wraps Steam Audio in safe Rust types while explicitly hunting down thread-safety and segfault issues. If you're building spatial audio in Rust the ergonomic API, HRTF support and focused safety fixes make this a practical, low-friction choice — not revolutionary, but professionally executed for its niche.

Niche GemWizardry
mxncmr
103mo ago