New posts for Spring and Hibernate
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
# javap of the shipped hibernate-core-7.4.14.Final.jar
|
||||
|
||||
$ javap -cp hibernate-core-7.4.14.Final.jar org.hibernate.annotations.UuidGenerator
|
||||
Compiled from "UuidGenerator.java"
|
||||
public interface org.hibernate.annotations.UuidGenerator extends java.lang.annotation.Annotation {
|
||||
public abstract org.hibernate.annotations.UuidGenerator$Style style();
|
||||
public abstract java.lang.Class<? extends org.hibernate.id.uuid.UuidValueGenerator> algorithm();
|
||||
}
|
||||
|
||||
$ javap -cp hibernate-core-7.4.14.Final.jar org.hibernate.annotations.UuidGenerator$Style
|
||||
Compiled from "UuidGenerator.java"
|
||||
public final class org.hibernate.annotations.UuidGenerator$Style extends java.lang.Enum<org.hibernate.annotations.UuidGenerator$Style> {
|
||||
public static final org.hibernate.annotations.UuidGenerator$Style AUTO;
|
||||
public static final org.hibernate.annotations.UuidGenerator$Style RANDOM;
|
||||
public static final org.hibernate.annotations.UuidGenerator$Style TIME;
|
||||
public static final org.hibernate.annotations.UuidGenerator$Style VERSION_6;
|
||||
public static final org.hibernate.annotations.UuidGenerator$Style VERSION_7;
|
||||
public static org.hibernate.annotations.UuidGenerator$Style[] values();
|
||||
public static org.hibernate.annotations.UuidGenerator$Style valueOf(java.lang.String);
|
||||
static {};
|
||||
}
|
||||
|
||||
$ javap -cp hibernate-core-7.4.14.Final.jar org.hibernate.id.uuid.UuidValueGenerator
|
||||
Compiled from "UuidValueGenerator.java"
|
||||
public interface org.hibernate.id.uuid.UuidValueGenerator {
|
||||
public abstract java.util.UUID generateUuid(org.hibernate.engine.spi.SharedSessionContractImplementor);
|
||||
}
|
||||
|
||||
$ javap -cp hibernate-core-7.4.14.Final.jar org.hibernate.id.uuid.UuidVersion7Strategy
|
||||
Compiled from "UuidVersion7Strategy.java"
|
||||
public class org.hibernate.id.uuid.UuidVersion7Strategy implements org.hibernate.id.UUIDGenerationStrategy,org.hibernate.id.uuid.UuidValueGenerator {
|
||||
public static final org.hibernate.id.uuid.UuidVersion7Strategy INSTANCE;
|
||||
public org.hibernate.id.uuid.UuidVersion7Strategy();
|
||||
public org.hibernate.id.uuid.UuidVersion7Strategy(java.time.Instant, long);
|
||||
public int getGeneratedVersion();
|
||||
public java.util.UUID generateUUID(org.hibernate.engine.spi.SharedSessionContractImplementor);
|
||||
public java.util.UUID generateUuid(org.hibernate.engine.spi.SharedSessionContractImplementor);
|
||||
static {};
|
||||
}
|
||||
|
||||
$ javap -cp hibernate-core-7.4.14.Final.jar org.hibernate.id.SequenceMismatchStrategy
|
||||
Compiled from "SequenceMismatchStrategy.java"
|
||||
public final class org.hibernate.id.SequenceMismatchStrategy extends java.lang.Enum<org.hibernate.id.SequenceMismatchStrategy> {
|
||||
public static final org.hibernate.id.SequenceMismatchStrategy LOG;
|
||||
public static final org.hibernate.id.SequenceMismatchStrategy EXCEPTION;
|
||||
public static final org.hibernate.id.SequenceMismatchStrategy FIX;
|
||||
public static final org.hibernate.id.SequenceMismatchStrategy NONE;
|
||||
public static org.hibernate.id.SequenceMismatchStrategy[] values();
|
||||
public static org.hibernate.id.SequenceMismatchStrategy valueOf(java.lang.String);
|
||||
public static org.hibernate.id.SequenceMismatchStrategy interpret(java.lang.Object);
|
||||
static {};
|
||||
}
|
||||
|
||||
$ javap -cp hibernate-core-7.4.14.Final.jar org.hibernate.id.enhanced.StandardOptimizerDescriptor
|
||||
Compiled from "StandardOptimizerDescriptor.java"
|
||||
public final class org.hibernate.id.enhanced.StandardOptimizerDescriptor extends java.lang.Enum<org.hibernate.id.enhanced.StandardOptimizerDescriptor> implements org.hibernate.id.enhanced.OptimizerDescriptor {
|
||||
public static final org.hibernate.id.enhanced.StandardOptimizerDescriptor NONE;
|
||||
public static final org.hibernate.id.enhanced.StandardOptimizerDescriptor HILO;
|
||||
public static final org.hibernate.id.enhanced.StandardOptimizerDescriptor LEGACY_HILO;
|
||||
public static final org.hibernate.id.enhanced.StandardOptimizerDescriptor POOLED;
|
||||
public static final org.hibernate.id.enhanced.StandardOptimizerDescriptor POOLED_LO;
|
||||
public static final org.hibernate.id.enhanced.StandardOptimizerDescriptor POOLED_LOTL;
|
||||
public static org.hibernate.id.enhanced.StandardOptimizerDescriptor[] values();
|
||||
public static org.hibernate.id.enhanced.StandardOptimizerDescriptor valueOf(java.lang.String);
|
||||
public java.lang.String getExternalName();
|
||||
public java.lang.Class<? extends org.hibernate.id.enhanced.Optimizer> getOptimizerClass();
|
||||
public boolean isPooled();
|
||||
public static org.hibernate.id.enhanced.OptimizerDescriptor fromExternalName(java.lang.String);
|
||||
static {};
|
||||
}
|
||||
|
||||
$ javap java.util.UUID (static members only)
|
||||
public static java.util.UUID randomUUID();
|
||||
public static java.util.UUID nameUUIDFromBytes(byte[]);
|
||||
public static java.util.UUID fromString(java.lang.String);
|
||||
static {};
|
||||
@@ -0,0 +1,7 @@
|
||||
# UuidGenerator.Style constants per hibernate-core release (javap of each jar; produced by hand while writing the article, not by scripts/run-all.sh)
|
||||
|
||||
hibernate-core-6.5.2.Final: AUTO RANDOM TIME | UuidVersion7Strategy in jar: 0
|
||||
hibernate-core-6.6.8.Final: AUTO RANDOM TIME | UuidVersion7Strategy in jar: 0
|
||||
hibernate-core-7.0.0.Final: AUTO RANDOM TIME VERSION_6 VERSION_7 | UuidVersion7Strategy in jar: 1
|
||||
hibernate-core-7.4.0.Final: AUTO RANDOM TIME VERSION_6 VERSION_7 | UuidVersion7Strategy in jar: 1
|
||||
hibernate-core-7.4.14.Final: AUTO RANDOM TIME VERSION_6 VERSION_7 | UuidVersion7Strategy in jar: 1
|
||||
@@ -0,0 +1,57 @@
|
||||
UuidGenerator.Style values and what the generated UUIDs look like. Hibernate 7.4.14.Final, JDK 25.0.3+9-LTS-195
|
||||
|
||||
== The enum and the annotation, from the shipped jar
|
||||
Style values : [AUTO, RANDOM, TIME, VERSION_6, VERSION_7]
|
||||
annotation attributes : [algorithm, style]
|
||||
|
||||
== Does the JDK itself generate version 7? (public static methods of java.util.UUID)
|
||||
static factories: [fromString, nameUUIDFromBytes, randomUUID]
|
||||
|
||||
== GenerationType.UUID (JPA) (UuidV4Item, 2000 persists in one transaction)
|
||||
first three : [5b257f75-63bc-4f48-905d-65bac3459d13, 8b636cac-72ba-4740-baa4-960522598e0f, 7563a4d5-dfe5-4be5-b1f5-55e71a83eaec]
|
||||
version nibble of every id : [4], variant : [2]
|
||||
string/byte order vs generation order : 1017 of 1999 neighbours are out of order
|
||||
|
||||
== bare @GeneratedValue on a UUID (AUTO) (AutoUuidItem, 2000 persists in one transaction)
|
||||
first three : [35ad5be5-7f04-4dc8-83b9-f2266e101ab0, 78a0cefb-b172-46e4-94aa-60212ad0b190, 162be54a-33b8-4018-8df9-5e43836cc2af]
|
||||
version nibble of every id : [4], variant : [2]
|
||||
string/byte order vs generation order : 1005 of 1999 neighbours are out of order
|
||||
|
||||
== Style.TIME (UuidTimeItem, 2000 persists in one transaction)
|
||||
first three : [c0a802bb-a1ad-1754-81a1-ad076a3225a0, c0a802bb-a1ad-1754-81a1-ad076a3225a1, c0a802bb-a1ad-1754-81a1-ad076a3225a2]
|
||||
version nibble of every id : [1], variant : [2]
|
||||
string/byte order vs generation order : 0 of 1999 neighbours are out of order
|
||||
UUID.timestamp() of first / last id (100ns ticks since 1582) : 528224823942841019 / 528224823942841019
|
||||
most significant 32 bits (time_low) of first three : [c0a802bb, c0a802bb, c0a802bb]
|
||||
|
||||
== Style.VERSION_6 (UuidV6Item, 2000 persists in one transaction)
|
||||
first three : [1f1d9490-534d-6627-8be9-341e19966c04, 1f1d9490-534d-6627-8bea-9c10655ddb7b, 1f1d9490-534d-6627-8beb-b5f923905e48]
|
||||
version nibble of every id : [6], variant : [2]
|
||||
string/byte order vs generation order : 0 of 1999 neighbours are out of order
|
||||
|
||||
== Style.VERSION_7 (UuidV7Item, 2000 persists in one transaction)
|
||||
first three : [01a1ad07-6af9-7f60-91e5-a074a2e61b15, 01a1ad07-6af9-7f60-bafb-92ecaabdd57e, 01a1ad07-6af9-7f61-84be-68a7813aa2e1]
|
||||
version nibble of every id : [7], variant : [2]
|
||||
string/byte order vs generation order : 0 of 1999 neighbours are out of order
|
||||
first 48 bits as Unix milliseconds : 1793904306937 -> 2026-11-05T18:45:06.937Z
|
||||
|
||||
== uuid-creator getTimeOrderedEpoch() (UuidCreatorV7Item, 2000 persists in one transaction)
|
||||
first three : [01a1ad07-6b4a-7727-8708-c7b485cd7cc5, 01a1ad07-6b4a-7727-8709-75a505ff49d2, 01a1ad07-6b4a-7727-870a-1991eca1f5b5]
|
||||
version nibble of every id : [7], variant : [2]
|
||||
string/byte order vs generation order : 0 of 1999 neighbours are out of order
|
||||
first 48 bits as Unix milliseconds : 1793904307018 -> 2026-11-05T18:45:07.018Z
|
||||
|
||||
== hand-written UuidV7Generator (HandRolledV7Item, 2000 persists in one transaction)
|
||||
first three : [01a1ad07-6ba5-7041-a4e3-8df974d6a001, 01a1ad07-6ba5-7042-8be9-c72dadba0e18, 01a1ad07-6ba5-7043-87de-73e7de8dbb54]
|
||||
version nibble of every id : [7], variant : [2]
|
||||
string/byte order vs generation order : 0 of 1999 neighbours are out of order
|
||||
first 48 bits as Unix milliseconds : 1793904307109 -> 2026-11-05T18:45:07.109Z
|
||||
|
||||
== Style.TIME is not a clock-ordered v1: what changes between ids created 30 ms apart
|
||||
c0a802bb-a1ad-1754-81a1-ad076be82d70 msb=c0a802bba1ad1754 lsb=81a1ad076be82d70
|
||||
c0a802bb-a1ad-1754-81a1-ad076c092d71 msb=c0a802bba1ad1754 lsb=81a1ad076c092d71
|
||||
c0a802bb-a1ad-1754-81a1-ad076c282d72 msb=c0a802bba1ad1754 lsb=81a1ad076c282d72
|
||||
c0a802bb-a1ad-1754-81a1-ad076c482d73 msb=c0a802bba1ad1754 lsb=81a1ad076c482d73
|
||||
distinct most-significant halves among them : 1 (IPv4 address of this host + a per-JVM value, fixed for the life of the JVM)
|
||||
first 32 bits equal this host's IPv4 address : true
|
||||
UUID.timestamp() (what a real version 1 would use as its clock) is the same for all four : 1 distinct value(s)
|
||||
@@ -0,0 +1,7 @@
|
||||
Cost of generating one UUID in memory (single thread, 2,000,000 ids after 500,000 warm-up; indicative, machine dependent)
|
||||
UUID.randomUUID() 351 ns per id
|
||||
Hibernate VERSION_7 769 ns per id
|
||||
Hibernate VERSION_6 680 ns per id
|
||||
Hibernate TIME (v1) 22 ns per id
|
||||
uuid-creator v7 352 ns per id
|
||||
UuidV7Generator (hand-written) 709 ns per id
|
||||
@@ -0,0 +1,43 @@
|
||||
IDENTITY vs SEQUENCE vs TABLE: generated DDL, SQL, and when the INSERT runs
|
||||
|
||||
######## H2 ########
|
||||
database: H2Dialect / H2 2.4.240 (2025-09-22)
|
||||
|
||||
== DDL Hibernate generates
|
||||
create sequence seq_one_item start with 1 increment by 1;
|
||||
create sequence seq_pooled_item start with 1 increment by 50;
|
||||
create sequence SeqDefaultItem_SEQ start with 1 increment by 50;
|
||||
create table hibernate_sequences (next_val bigint, sequence_name varchar(255) not null, primary key (sequence_name));
|
||||
insert into hibernate_sequences(sequence_name, next_val) values ('default',0);
|
||||
create table IdentityItem (id bigint generated by default as identity, name varchar(255), primary key (id));
|
||||
create table SeqDefaultItem (id bigint not null, name varchar(255), primary key (id));
|
||||
create table SeqOneItem (id bigint not null, name varchar(255), primary key (id));
|
||||
create table SeqPooledItem (id bigint not null, name varchar(255), primary key (id));
|
||||
create table TableItem (id bigint not null, name varchar(255), primary key (id));
|
||||
|
||||
== IDENTITY: persist() runs the INSERT immediately
|
||||
-- persist(item) -- no flush(), no commit() yet
|
||||
sql> insert into IdentityItem (name,id) values (?,default)
|
||||
item.getId() right after persist : 1
|
||||
rows visible after rollback : 0
|
||||
|
||||
== SEQUENCE, allocationSize = 1: one sequence call per entity
|
||||
persist 120 entities, one transaction
|
||||
sequence calls : 120 inserts : 120
|
||||
first ids : [1, 2, 3, 4, 5] ... last id : 120
|
||||
|
||||
== SEQUENCE, allocationSize = 50 (pooled optimizer): one sequence call per 50 entities
|
||||
persist 120 entities, one transaction
|
||||
sequence calls : 4 inserts : 120
|
||||
first ids : [1, 2, 3, 4, 5] ... last id : 120
|
||||
sequence statements : [select next value for seq_pooled_item]
|
||||
(the first allocation of a fresh sequence costs two calls: one to learn the starting value, one to learn the upper bound of the first block of 50)
|
||||
persist another 120 entities, same SessionFactory : sequence calls : 2
|
||||
|
||||
== TABLE generator: one read + one update of the generator row per allocation
|
||||
persist 120 entities: statements other than the 120 INSERTs : 8 (seen by the JDBC counter; Hibernate's StatementInspector does not see them)
|
||||
sql> select next_val from hibernate_sequences where sequence_name=? for update
|
||||
sql> update hibernate_sequences set next_val=? where next_val=? and sequence_name=?
|
||||
|
||||
######## POSTGRES ########
|
||||
SKIPPED: no Docker daemon was reachable when this transcript was generated, so PostgreSQL was not run.
|
||||
@@ -0,0 +1,17 @@
|
||||
Sequence names Hibernate 7 picks when you name nothing, and the legacy switch
|
||||
|
||||
######## H2 ########
|
||||
database: H2Dialect / H2 2.4.240 (2025-09-22)
|
||||
|
||||
== hibernate.id.db_structure_naming_strategy = standard (entities: AutoLongItem, SeqDefaultItem)
|
||||
create sequence AutoLongItem_SEQ start with 1 increment by 50;
|
||||
create sequence SeqDefaultItem_SEQ start with 1 increment by 50;
|
||||
|
||||
== hibernate.id.db_structure_naming_strategy = legacy (entities: AutoLongItem, SeqDefaultItem)
|
||||
create sequence hibernate_sequence start with 1 increment by 1;
|
||||
|
||||
== hibernate.id.db_structure_naming_strategy = single (entities: AutoLongItem, SeqDefaultItem)
|
||||
create sequence hibernate_sequence start with 1 increment by 1;
|
||||
|
||||
######## POSTGRES ########
|
||||
SKIPPED: no Docker daemon was reachable when this transcript was generated, so PostgreSQL was not run.
|
||||
@@ -0,0 +1,19 @@
|
||||
10,000 inserts: IDENTITY vs SEQUENCE vs UUID, hibernate.jdbc.batch_size=50, flush+clear every 50 rows
|
||||
|
||||
######## H2 ########
|
||||
database: H2Dialect / H2 2.4.240 (2025-09-22)
|
||||
timings are wall-clock milliseconds on one developer machine, one run each after a warm-up pass: indicative, not a benchmark
|
||||
|
||||
IDENTITY 331 ms prepared=10000 (insert=10000, sequence=0) addBatch=0 executeBatch=0 executeSingle=10000
|
||||
SEQUENCE allocationSize=1 226 ms prepared=10200 (insert=200, sequence=10000) addBatch=10000 executeBatch=200 executeSingle=10000
|
||||
SEQUENCE allocationSize=50 46 ms prepared=400 (insert=200, sequence=200) addBatch=10000 executeBatch=200 executeSingle=200
|
||||
UUID v4 (GenerationType.UUID) 98 ms prepared=200 (insert=200, sequence=0) addBatch=10000 executeBatch=200 executeSingle=0
|
||||
UUID v7 (Style.VERSION_7) 64 ms prepared=200 (insert=200, sequence=0) addBatch=10000 executeBatch=200 executeSingle=0
|
||||
|
||||
Hibernate Statistics for the whole session factory (all rows above, including the warm-up): entityInsertCount=55000 prepareStatementCount=23101
|
||||
|
||||
Same SEQUENCE allocationSize=50 entity, hibernate.jdbc.batch_size NOT set:
|
||||
SEQUENCE allocationSize=50 68 ms prepared=10201 (insert=10000, sequence=201) addBatch=0 executeBatch=0 executeSingle=10201
|
||||
|
||||
######## POSTGRES ########
|
||||
SKIPPED: no Docker daemon was reachable when this transcript was generated, so PostgreSQL was not run.
|
||||
@@ -0,0 +1,9 @@
|
||||
hibernate.order_inserts on a parent/child graph (1,000 parents x 3 children, batch_size=50, flush+clear every 50 parents)
|
||||
|
||||
######## H2 ########
|
||||
database: H2Dialect / H2 2.4.240 (2025-09-22)
|
||||
order_inserts=false 266 ms prepared=2082 (insert=2000, sequence=82) addBatch=4000 executeBatch=2000 executeSingle=82
|
||||
order_inserts=true 118 ms prepared=122 (insert=40, sequence=82) addBatch=4000 executeBatch=80 executeSingle=82
|
||||
|
||||
######## POSTGRES ########
|
||||
SKIPPED: no Docker daemon was reachable when this transcript was generated, so PostgreSQL was not run.
|
||||
@@ -0,0 +1,30 @@
|
||||
Mapping says allocationSize=50, the database sequence says INCREMENT BY 1 (schema created by hand)
|
||||
|
||||
######## H2 ########
|
||||
|
||||
== hibernate.id.sequence.increment_size_mismatch_strategy = (unset)
|
||||
SessionFactory startup FAILED: MappingException -> MappingException: The increment size of the [seq_pooled_item] sequence is set to [50] in the entity mapping but the mapped database sequence increment size is [1]
|
||||
|
||||
== hibernate.id.sequence.increment_size_mismatch_strategy = EXCEPTION
|
||||
SessionFactory startup FAILED: MappingException -> MappingException: The increment size of the [seq_pooled_item] sequence is set to [50] in the entity mapping but the mapped database sequence increment size is [1]
|
||||
|
||||
== hibernate.id.sequence.increment_size_mismatch_strategy = LOG
|
||||
SessionFactory started
|
||||
application instance A : ids [1, -47, -46]
|
||||
application instance B : FAILED after ids [-46, -45, -44] : ConstraintViolationException -> JdbcSQLIntegrityConstraintViolationException: SQLState 23505, Unique index or primary key violation: "PUBLIC.CONSTRAINT_D PRIMARY KEY ON PUBLIC.SEQPOOLEDITEM(ID) ( /* key:-46 */ CAST(-46 AS BIGINT), 'a2')"; SQL statement:
|
||||
database sequence INCREMENT BY, as the database sees it : 1
|
||||
|
||||
== hibernate.id.sequence.increment_size_mismatch_strategy = FIX
|
||||
SessionFactory started
|
||||
application instance A : ids [1, 2, 3]
|
||||
application instance B : ids [4, 5, 6]
|
||||
database sequence INCREMENT BY, as the database sees it : 1
|
||||
|
||||
== hibernate.id.sequence.increment_size_mismatch_strategy = NONE
|
||||
SessionFactory started
|
||||
application instance A : ids [1, -47, -46]
|
||||
application instance B : FAILED after ids [-46, -45, -44] : ConstraintViolationException -> JdbcSQLIntegrityConstraintViolationException: SQLState 23505, Unique index or primary key violation: "PUBLIC.CONSTRAINT_D PRIMARY KEY ON PUBLIC.SEQPOOLEDITEM(ID) ( /* key:-46 */ CAST(-46 AS BIGINT), 'a2')"; SQL statement:
|
||||
database sequence INCREMENT BY, as the database sees it : 1
|
||||
|
||||
######## POSTGRES ########
|
||||
SKIPPED: no Docker daemon was reachable when this transcript was generated, so PostgreSQL was not run.
|
||||
@@ -0,0 +1,12 @@
|
||||
Mapping says allocationSize=1, the database sequence says INCREMENT BY 50
|
||||
|
||||
######## H2 ########
|
||||
|
||||
== hibernate.id.sequence.increment_size_mismatch_strategy = (unset)
|
||||
ids : [1, 51, 101, 151]
|
||||
|
||||
== hibernate.id.sequence.increment_size_mismatch_strategy = FIX
|
||||
ids : [1, 51, 101, 151]
|
||||
|
||||
######## POSTGRES ########
|
||||
SKIPPED: no Docker daemon was reachable when this transcript was generated, so PostgreSQL was not run.
|
||||
@@ -0,0 +1,49 @@
|
||||
What @GeneratedValue (AUTO) and UUID ids become per dialect. DDL only: no database connection is opened for the dialects other than H2. Hibernate 7.4.14.Final
|
||||
|
||||
== H2 (org.hibernate.dialect.H2Dialect)
|
||||
create sequence AutoLongItem_SEQ start with 1 increment by 50;
|
||||
create table AutoLongItem (id bigint not null, name varchar(255), primary key (id));
|
||||
create table AutoUuidItem (id uuid not null, name varchar(255), primary key (id));
|
||||
create table IdentityItem (id bigint generated by default as identity, name varchar(255), primary key (id));
|
||||
create table UuidCharItem (id char(36) not null, name varchar(255), primary key (id));
|
||||
create table UuidV7Item (id uuid not null, name varchar(255), primary key (id));
|
||||
|
||||
== PostgreSQL (org.hibernate.dialect.PostgreSQLDialect)
|
||||
create sequence AutoLongItem_SEQ start with 1 increment by 50;
|
||||
create table AutoLongItem (id bigint not null, name varchar(255), primary key (id));
|
||||
create table AutoUuidItem (id uuid not null, name varchar(255), primary key (id));
|
||||
create table IdentityItem (id bigint generated by default as identity, name varchar(255), primary key (id));
|
||||
create table UuidCharItem (id char(36) not null, name varchar(255), primary key (id));
|
||||
create table UuidV7Item (id uuid not null, name varchar(255), primary key (id));
|
||||
|
||||
== MySQL (org.hibernate.dialect.MySQLDialect)
|
||||
create table AutoLongItem (id bigint not null, name varchar(255), primary key (id)) engine=InnoDB;
|
||||
create table AutoLongItem_SEQ (next_val bigint) engine=InnoDB;
|
||||
create table AutoUuidItem (id binary(16) not null, name varchar(255), primary key (id)) engine=InnoDB;
|
||||
create table IdentityItem (id bigint not null auto_increment, name varchar(255), primary key (id)) engine=InnoDB;
|
||||
create table UuidCharItem (id varchar(36) not null, name varchar(255), primary key (id)) engine=InnoDB;
|
||||
create table UuidV7Item (id binary(16) not null, name varchar(255), primary key (id)) engine=InnoDB;
|
||||
|
||||
== MariaDB (org.hibernate.dialect.MariaDBDialect)
|
||||
create sequence AutoLongItem_SEQ start with 1 increment by 50 nocache;
|
||||
create table AutoLongItem (id bigint not null, name varchar(255), primary key (id)) engine=InnoDB;
|
||||
create table AutoUuidItem (id binary(16) not null, name varchar(255), primary key (id)) engine=InnoDB;
|
||||
create table IdentityItem (id bigint not null auto_increment, name varchar(255), primary key (id)) engine=InnoDB;
|
||||
create table UuidCharItem (id varchar(36) not null, name varchar(255), primary key (id)) engine=InnoDB;
|
||||
create table UuidV7Item (id binary(16) not null, name varchar(255), primary key (id)) engine=InnoDB;
|
||||
|
||||
== Oracle (org.hibernate.dialect.OracleDialect)
|
||||
create sequence AutoLongItem_SEQ start with 1 increment by 50;
|
||||
create table AutoLongItem (id number(19,0) not null, name varchar2(255 char), primary key (id));
|
||||
create table AutoUuidItem (id raw(16) not null, name varchar2(255 char), primary key (id));
|
||||
create table IdentityItem (id number(19,0) generated by default as identity, name varchar2(255 char), primary key (id));
|
||||
create table UuidCharItem (id char(36) not null, name varchar2(255 char), primary key (id));
|
||||
create table UuidV7Item (id raw(16) not null, name varchar2(255 char), primary key (id));
|
||||
|
||||
== SQL Server (org.hibernate.dialect.SQLServerDialect)
|
||||
create sequence AutoLongItem_SEQ start with 1 increment by 50;
|
||||
create table AutoLongItem (id bigint not null, name varchar(255), primary key (id));
|
||||
create table AutoUuidItem (id uniqueidentifier not null, name varchar(255), primary key (id));
|
||||
create table IdentityItem (id bigint identity not null, name varchar(255), primary key (id));
|
||||
create table UuidCharItem (id char(36) not null, name varchar(255), primary key (id));
|
||||
create table UuidV7Item (id uniqueidentifier not null, name varchar(255), primary key (id));
|
||||
@@ -0,0 +1,8 @@
|
||||
Primary-key choice vs database file size, H2 file database (MVStore B-tree), file size after the database is closed, 200000 rows per variant, batch_size=50, flush+clear every 50 rows
|
||||
H2 specific: this is H2's storage engine, not PostgreSQL's or InnoDB's. Timings are indicative (one run, one machine).
|
||||
|
||||
variant load ms file KiB
|
||||
bigint sequence (allocationSize 50) 1244 4944
|
||||
UUID v4 random 2280 101428
|
||||
UUID v7 time-ordered 1314 12960
|
||||
UUID v7 as CHAR(36) 1528 52948
|
||||
@@ -0,0 +1,2 @@
|
||||
Primary-key choice vs index size and leaf density, PostgreSQL postgres:17-alpine, 200000 rows per variant, batch_size=50
|
||||
SKIPPED: no Docker daemon was reachable when this transcript was generated, so PostgreSQL was not run.
|
||||
@@ -0,0 +1,20 @@
|
||||
Spring Data JPA save() with application-assigned vs generated ids. Spring Boot parent 4.1.1, Hibernate 7.4.14.Final, H2
|
||||
|
||||
== AssignedBook: UUID.randomUUID() assigned in the constructor, no @Version
|
||||
sql> select ab1_0.id,ab1_0.title from assigned_book ab1_0 where ab1_0.id=?
|
||||
sql> insert into assigned_book (title,id) values (?,?)
|
||||
|
||||
== VersionedBook: same, plus a boxed @Version column
|
||||
sql> insert into versioned_book (title,version,id) values (?,?,?)
|
||||
|
||||
== PersistableBook: same, entity implements Persistable.isNew()
|
||||
sql> insert into persistable_book (title,id) values (?,?)
|
||||
|
||||
== GeneratedBook: @UuidGenerator(style = VERSION_7), id is null until persist
|
||||
sql> insert into generated_book (title,id) values (?,?)
|
||||
|
||||
== saveAll of 100 new AssignedBook rows: selects issued
|
||||
select statements : 100, insert statements : 100
|
||||
|
||||
== saveAll of 100 new GeneratedBook rows: selects issued
|
||||
select statements : 0, insert statements : 100
|
||||
Reference in New Issue
Block a user