Entities and primary keys

Hibernate · lesson 3 of 32 · 4 min read

Map a class to a table and pick an id strategy that will not hurt you later.

Open this lesson in the learning hub

Key points

  • @Entity marks a class Hibernate manages. It needs a no-arg constructor (protected is fine) and must not be final.
  • @Id marks the primary key. @GeneratedValue says the value is produced for you.
  • IDENTITY uses an auto-increment column. Simple, but Hibernate must run the INSERT immediately, so insert batching is off.
  • SEQUENCE fetches ids up front. With allocationSize (Hibernate defaults to 50) one round trip covers 50 rows and batching works.
  • GenerationType.UUID lets you assign ids in Java. Random UUIDs scatter index writes, so prefer a bigint sequence unless you need client-side ids.
  • Do not derive equals/hashCode from a generated id - it is null before the insert. Use a natural key, or leave both alone.

Example

import jakarta.persistence.*;
import java.time.LocalDate;

@Entity
@Table(name = "book")
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "book_seq")
    @SequenceGenerator(name = "book_seq", sequenceName = "book_seq", allocationSize = 50)
    private Long id;

    @Column(nullable = false, length = 200)
    private String title;

    @Column(name = "published_on")
    private LocalDate publishedOn;

    protected Book() {
        // required by JPA, not for application code
    }

    public Book(String title, LocalDate publishedOn) {
        this.title = title;
        this.publishedOn = publishedOn;
    }

    public Long getId() { return id; }
    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }
}

SEQUENCE with a healthy allocationSize is the boring, fast default.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Hibernate course, and every lesson in it is listed on the Hibernate contents page.