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.
52 lines
2.6 KiB
Markdown
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.
|