JPA/Hibernate Primary Key Generation Strategies

In Hibernate and JPA, primary key generation strategies determine how the primary key values are generated for entity objects. The @GeneratedValue annotation is used to specify the primary key generation strategy. There are several strategies available, each suitable for different use cases.

Primary Key Generation Strategies

  1. AUTO
  2. IDENTITY
  3. SEQUENCE
  4. TABLE
  5. UUID

Let's explore each strategy with code snippets.

1. AUTO Strategy

The AUTO strategy allows the persistence provider (e.g., Hibernate) to choose the generation strategy. It might use SEQUENCE, IDENTITY, or TABLE based on the underlying database.

Example:

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    // Getters and Setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2. IDENTITY Strategy

The IDENTITY strategy relies on the database to generate the primary key value. Typically, it uses an auto-increment column.

Example:

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    // Getters and Setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

3. SEQUENCE Strategy

The SEQUENCE strategy uses a database sequence to generate unique values. This strategy is particularly useful for databases that support sequences (e.g., Oracle, PostgreSQL).

Example:

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.SequenceGenerator;

@Entity
@SequenceGenerator(name = "product_seq", sequenceName = "product_sequence", allocationSize = 1)
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "product_seq")
    private Long id;

    private String name;

    // Getters and Setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

4. TABLE Strategy

The TABLE strategy uses a dedicated database table to generate primary key values. This strategy is database-independent but might have performance implications due to additional database access.

Example:

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.TableGenerator;

@Entity
@TableGenerator(name = "product_gen", table = "id_gen", pkColumnName = "gen_name", valueColumnName = "gen_val", initialValue = 0, allocationSize = 1)
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "product_gen")
    private Long id;

    private String name;

    // Getters and Setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

5. UUID Strategy

The UUID strategy uses universally unique identifiers (UUID) as primary keys. This is useful for distributed systems where uniqueness across different databases is required.

Example with UUID Generation:

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import java.util.UUID;

@Entity
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    private UUID id;

    private String name;

    // Getters and Setters
    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Example with UUID and Hibernate's UUIDGenerator:

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import org.hibernate.annotations.GenericGenerator;

import java.util.UUID;

@Entity
public class Product {

    @Id
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(
        name = "UUID",
        strategy = "org.hibernate.id.UUIDGenerator"
    )
    private UUID id;

    private String name;

    // Getters and Setters
    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Conclusion

In this blog post, we explored different primary key generation strategies in Hibernate and JPA, including. AUTO, IDENTITY, SEQUENCE, TABLE, and UUID. Each strategy has its own use case and advantages, and understanding these strategies can help you choose the best one for your application's requirements.

Comments