3.6 KiB
id-generation
Companion module for the ankurm.com article Hibernate ID Generation: IDENTITY vs SEQUENCE vs UUID v7, and Why Batch Inserts Break
(https://ankurm.com/hibernate-id-generation-identity-sequence-uuid-v7-batch-inserts/).
Every claim in the article comes from a test here; each test writes what it observed to output/ and asserts the same facts.
Versions
| Component | Version | Notes |
|---|---|---|
| Hibernate ORM | 7.4.14.Final |
newest 7.x GA on Maven Central on 2026-11-05 (8.0.0.Beta4 is listed but is not GA). Overrides the 7.4.5.Final that Spring Boot 4.1.1 manages, same as soft-delete |
| Spring Boot parent | 4.1.1 |
same parent as the sibling modules (4.1.2 was already on Maven Central; not adopted so the modules stay comparable) |
| uuid-creator | 6.1.1 |
only for one comparison generator |
| H2 | 2.4.240 |
in memory, plus file databases for the index-size test |
| PostgreSQL | 17 (postgres:17-alpine) |
Testcontainers. Not run for the committed transcripts, see below |
| Java | 25 (Temurin/Oracle 25.0.3) |
Run
./scripts/run-all.sh # javap dump + mvn clean test; regenerates everything in output/
Tests that can use PostgreSQL run against it when a Docker daemon answers and otherwise write SKIPPED: no Docker daemon ... into the
transcript. The committed transcripts were produced without Docker, so every PostgreSQL section says SKIPPED and the PostgreSQL code paths
(including 06b-index-size-postgres.txt: pg_relation_size, pgstatindex) have not been executed. Run the script on a machine with Docker to fill them in.
Output
| File | What it shows |
|---|---|
00-javap.txt |
javap of UuidGenerator, UuidGenerator$Style, UuidValueGenerator, UuidVersion7Strategy, SequenceMismatchStrategy, StandardOptimizerDescriptor and the static members of java.util.UUID |
00b-style-by-version.txt |
the Style constants in hibernate-core 6.5.2, 6.6.8, 7.0.0, 7.4.0, 7.4.14 (hand-run javap, not regenerated by the script) |
01-uuid-styles.txt |
version nibble, variant and ordering of ids from every Style, the JDK's UUID factories, what Style.TIME really contains |
01b-uuid-generation-rate.txt |
in-memory cost of generating one id per generator (indicative) |
02-identity-vs-sequence.txt |
DDL per strategy, IDENTITY insert at persist(), sequence calls for allocationSize 1 vs 50, TABLE generator statements |
02b-default-sequence-naming.txt |
default sequence names and the legacy / single naming switch |
03-batch-inserts.txt |
10,000 inserts per strategy: prepared statements, addBatch, executeBatch counts, indicative timings |
03b-order-inserts.txt |
hibernate.order_inserts on a parent/child graph |
04-sequence-increment-mismatch.txt |
mapping allocationSize=50 over a sequence INCREMENT BY 1, under each mismatch strategy |
04b-sequence-step-bigger-than-mapping.txt |
mapping allocationSize=1 over a sequence INCREMENT BY 50 |
05-auto-and-uuid-per-dialect.txt |
what @GeneratedValue and UUID columns become on H2, PostgreSQL, MySQL, MariaDB, Oracle, SQL Server (DDL only) |
06-index-size-h2.txt |
200,000 rows per key type in an H2 file database: file size |
06b-index-size-postgres.txt |
the same on PostgreSQL (SKIPPED without Docker) |
07-spring-data-save.txt |
save() on assigned vs generated ids: which ones cost a SELECT first |
Not covered (not run)
MySQL / InnoDB clustered-index behaviour, SQL Server, Oracle (DDL only), PostgreSQL index measurements, multi-node clock skew, hibernate.id.optimizer.pooled.preferred variants.