# 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.