How to set a custom initial value for Ids in JPA

In Java Persistence API (JPA), entities require unique identifiers for database records. JPA provides several strategies for generating these identifiers, such as IDENTITY, SEQUENCE, and TABLE. However, there are cases where you might need to set a custom initial value for these identifiers using the Table and Sequence strategy. In this tutorial, we will explore how to do this and discuss when it’s beneficial to customize the initial values for IDs.

Prerequisites and Use cases

Before we begin, make sure you have a basic understanding of JPA Strategies for Primary keys: Choosing the Strategy for Primary keys in JPA

Then, let’s see which are the most common use cases to set a custom initial value for your Entity Ids:

  • Legacy Data Integration: When you are integrating JPA with an existing database schema that already includes data, the primary key values in that database might not start from 1. In such cases, you would set the initial value of the @Id field to match the highest existing primary key value.
  • Data Sharding: In a distributed database environment where data is sharded across multiple nodes or databases, each shard may have its own range of primary key values. Setting different initial values for the primary key in each shard ensures that there is no overlap in primary key values between shards.

After the theory, let’s review which are the options to set a custom initial value for your Entity.

Example 1: Initial Value with Table Strategy

The Table strategy allows you to manage the allocation of primary key values using a database table. Here’s how to set a custom initial value using this strategy:

@Entity
@TableGenerator(
    name = "Custom_Gen",
    table = "ID_GEN",
    pkColumnName = "GEN_NAME",
    valueColumnName = "GEN_VAL",
    pkColumnValue = "Custom_Gen",
    initialValue = 1000, // Set your desired initial value
    allocationSize = 50 // Adjust allocation size as needed
)
public class EntityWithCustomTableStrategy {

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

    // Other entity properties and methods
}

In this example, we’ve defined a custom table generator named Custom_Gen with an initial value of 1000. The generator will allocate IDs starting from this value.

Example 2: Initial value using the Sequence Strategy

The Sequence strategy allows you to use a database sequence to generate IDs. To set a custom initial value using this strategy, you can adjust the sequence’s starting value in your database:

-- Example for PostgreSQL
CREATE SEQUENCE custom_sequence
    START WITH 1000; -- Set your desired initial value

Then, annotate your entity as follows:

@Entity
@SequenceGenerator(
    name = "Custom_Sequence",
    sequenceName = "custom_sequence",
    initialValue = 1000, // Same as the sequence's starting value
    allocationSize = 1 // Adjust allocation size as needed
)
public class EntityWithCustomSequenceStrategy {

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

    // Other entity properties and methods
}

In this case, the sequence’s initial value is set to 1000, matching the starting value defined in the sequence itself. Therefore, upon creation of a new Entity, the Id will be the next value of the sequence. For example:

entity how to set the initial value Id

Conclusion

Customizing initial values for IDs in JPA using Table and Sequence strategies provides flexibility in scenarios where you need precise control over ID generation. It is especially useful during data migration, when integrating with existing systems, or when enforcing specific ID patterns. However, carefully consider the necessity for customization, as it can add complexity to your application. Custom initial values should be used when they offer clear advantages in managing ID generation for your database records.

Found the article helpful? if so please follow us on Socials