Files
hibernate-demo/inheritance/README.md
T
asmhatre 807f681ed1 Add inheritance module: SINGLE_TABLE vs JOINED vs TABLE_PER_CLASS on Hibernate 7.4.13.Final
Same payment hierarchy mapped three ways plus @MappedSuperclass, run with plain Hibernate on H2.
Tests assert and write the generated DDL, the INSERT/SELECT SQL, row/insert/FK/nullability counts and
the three failures (NOT NULL on a SINGLE_TABLE subclass column, IDENTITY with TABLE_PER_CLASS, querying a
@MappedSuperclass); Bench writes indicative polymorphic-query timings. No docs folder: depth lives in the post.
2026-10-24 10:02:28 +00:00

52 lines
2.6 KiB
Markdown

# inheritance
Companion module for the ankurm.com article on **Hibernate 7 inheritance mapping: `SINGLE_TABLE` vs `JOINED` vs
`TABLE_PER_CLASS`**. One payment hierarchy (a root with card, bank-transfer and wallet subclasses, plus an order that
points at the root) mapped three ways, run against plain Hibernate (no Spring) and in-memory H2, with every statement
Hibernate generates captured in `output/`.
## Versions
| Component | Version | Notes |
|---|---|---|
| Hibernate ORM | `7.4.13.Final` | latest 7.x GA on Maven Central on 2026-10-24 (`8.0.0.Beta3` is also listed; it is not GA) |
| Jakarta Persistence | `3.2.0` | |
| H2 | `2.4.240` | in memory, `OPTIMIZE_REUSE_RESULTS=0` (see `Db.java`) |
| JUnit Jupiter / AssertJ | `6.0.3` / `3.27.7` | |
| Java | `25` (Temurin 25.0.5+8) | |
This module has its own `pom.xml` and does not use the Spring Boot parent of the main `hibernate-demo` project, so its
Hibernate patch version differs from the one that project pins.
## Run
```bash
./scripts/run-all.sh # JUnit tests, then the timing run; regenerates everything in output/
./scripts/bench.sh # only the timing run
```
## Layout
| Path | What it is |
|---|---|
| `src/main/java/com/ankurm/inheritance/single` | `Payment` hierarchy, `SINGLE_TABLE`, discriminator column, `@Check` constraint |
| `src/main/java/com/ankurm/inheritance/joined` | the same hierarchy, `JOINED` |
| `src/main/java/com/ankurm/inheritance/tpc` | the same hierarchy, `TABLE_PER_CLASS` (sequence ids, abstract root) |
| `src/main/java/com/ankurm/inheritance/mapped` | `@MappedSuperclass` `AuditedBase` with two unrelated entities |
| `src/test/java/.../Strategies.java` | the three hierarchies side by side |
| `src/test/java/.../DdlTest.java` | writes `output/01-*` |
| `src/test/java/.../SqlTest.java` | writes `output/02-*` |
| `src/test/java/.../ContractsTest.java` | writes `output/03-contracts.txt`; also holds the two deliberately wrong mappings (`Sn*`, `TpcIdentity*`) |
| `src/test/java/.../Bench.java` | writes `output/04-polymorphic-timings.txt` |
## Output
| File | What it shows |
|---|---|
| `output/01-ddl-single-table.txt`, `01-ddl-joined.txt`, `01-ddl-table-per-class.txt`, `01-ddl-mapped-superclass.txt` | the schema Hibernate generates |
| `output/02-sql-single-table.txt`, `02-sql-joined.txt`, `02-sql-table-per-class.txt` | INSERTs and SELECTs for the same four operations |
| `output/03-contracts.txt` | row counts, INSERT counts, nullability, foreign keys, and the three failures |
| `output/04-polymorphic-timings.txt` | indicative timings on 150,000 rows (not asserted; drift between runs) |
Everything in `01`-`03` is produced by tests that assert the numbers they print.