Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_017ic4b5sejRr8s3kapmRY2g
45 lines
2.2 KiB
Markdown
45 lines
2.2 KiB
Markdown
# projections
|
|
|
|
Companion code for **Spring Data JPA Projections: Interface, Record and Dynamic Projections (With the SQL They Generate)** on [ankurm.com](https://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.
|
|
|
|
```bash
|
|
./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.
|