पाठ 8 / 25
Primary Keys and ID Generation
Choose ID generation strategies and map natural and composite keys.
Identifiers and how they are generated
Every entity needs a primary key. @GeneratedValue strategies: SEQUENCE uses a database sequence and is the best choice where supported (PostgreSQL, Oracle, SQL Server, MariaDB, H2); with an allocationSize (for example 50) Hibernate reserves blocks of IDs and avoids a round trip per insert, and IDs are known before the INSERT, enabling JDBC batching. IDENTITY uses auto-increment columns (common in MySQL); the ID is known only after the INSERT, so Hibernate must insert immediately on persist and cannot batch inserts. TABLE emulates sequences with a table and scales poorly. AUTO lets the provider choose. UUID (JPA 3.1+, or Hibernate's @UuidGenerator) generates identifiers in the application, convenient for distributed systems and for creating IDs before persisting; time-ordered UUIDs (version 7) index better than random version 4. Business keys such as an ISBN or email can be mapped with @NaturalId and a unique constraint while keeping a surrogate primary key. Composite keys use @EmbeddedId or @IdClass, mostly for join tables and legacy schemas.
Sequence, UUID and composite keys
Sequence IDs with block allocation, application-generated UUIDs and an embedded composite key.
@Entity
public class Invoice {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "invoice_seq")
@SequenceGenerator(name = "invoice_seq", sequenceName = "invoices_seq", allocationSize = 50)
private Long id; // batch-friendly; matches INCREMENT BY 50 in the DB
}
@Entity
public class Device {
@Id
@GeneratedValue(strategy = GenerationType.UUID) // JPA 3.1+
private UUID id;
@NaturalId // Hibernate: business key, still unique in DB
@Column(nullable = false, unique = true)
private String serialNumber;
}
@Embeddable
public record EnrolmentId(Long studentId, String courseCode) implements Serializable { }
@Entity
public class Enrolment {
@EmbeddedId
private EnrolmentId id;
private String grade;
}Token numbers at a counter
A sequence with an allocation size is like a clerk who collects a booklet of 50 token numbers at once instead of walking back to the dispenser for each customer. IDENTITY is getting each number only after the customer is already seated.
त्वरित जाँच: Why can IDENTITY ID generation prevent Hibernate from batching inserts?
- IDENTITY IDs are random
- IDENTITY is not supported by JDBC
- Batching requires UUIDs
- The ID is only known after each INSERT executes, so Hibernate must insert immediately on persist
Answer
The ID is only known after each INSERT executes, so Hibernate must insert immediately on persist — Hibernate needs the generated key right away, forcing one INSERT per persist.