Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_017ic4b5sejRr8s3kapmRY2g
2.2 KiB
2.2 KiB
projections
Companion code for Spring Data JPA Projections: Interface, Record and Dynamic Projections (With the SQL They Generate) on ankurm.com.
| Component | Version |
|---|---|
| Spring Boot | 4.1.2 |
| Spring Data JPA | 4.1.2 |
| Hibernate ORM | 7.4.13.Final |
| H2 (in-memory) | 2.4.240 |
| JDK | Temurin 25.0.5 LTS |
No Docker needed. Every SQL statement is captured by SqlRecorder, a Hibernate StatementInspector, and every test writes the SQL it saw to output/ while asserting the same facts, so the numbers in the post fail the build if they stop being true.
./scripts/run-all.sh # regenerates every file in output/
| Source file | What it shows |
|---|---|
EmployeeSummary |
closed interface projection |
EmployeeFullName |
open interface projection (@Value SpEL) |
EmployeeFullNameClosed |
the fix for the open projection: a default method |
EmployeeWithDepartment |
nested interface projection |
EmployeeDto |
record DTO projection |
DepartmentPay |
target of a JPQL constructor expression |
EmployeeRepository |
every query-method form, numbered 1 to 14 |
SqlRecorder |
the SQL capture mechanism |
| Transcript | Shows |
|---|---|
output/01-entity-vs-closed-vs-dto.txt |
7 columns vs 2 columns, managed entities 4 vs 0 |
output/02-open-projection-trap.txt |
an open projection selects all 7 columns |
output/11-default-method-fix.txt |
a default method keeps the projection closed (2 columns) |
output/03-nested-projection.txt |
nested projection pulls the whole department row |
output/04-dynamic-projection.txt |
one method, three shapes |
output/05-query-forms.txt |
@Query aliases, constructor expression, native query |
output/06-pitfall-entity-query.txt |
select e declared as an interface projection loads everything |
output/07-pitfall-missing-aliases.txt |
tuple select without aliases returns nulls |
output/08-pitfall-unknown-property.txt |
unknown projection property |
output/09-paging-and-proxy.txt |
paging runs a count query; projections are JDK proxies |
output/10-entity-query-as-dto-rewrite.txt |
select e declared as a record is rewritten to 2 columns |
There is no docs/ folder: the explanations live in the post.