Loading...

The Hi/Lo Algorithm in Hibernate: Optimizing Database Identifier Generation

JPA
July 19, 2023
3 minutes to read
Share this post:

In the world of JVM persistence, Hibernate has a firm place. As one of the most popular frameworks for data persistence, it offers a multitude of possibilities to make developers’ lives easier. One of these possibilities is the Hi/Lo algorithm, a database identifier generation strategy that allows reducing the number of database calls when new entities are persisted.

The Challenge of Identifier Generation

Before we dive into the Hi/Lo algorithm, let’s briefly look at the challenge of identifier generation in a database. Every entity in a database needs a unique identifier (often referred to as ID) to distinguish it from other entities. With each insertion of a new entity into the database, the sequence on the database is usually queried to get the next ID for numerical IDs. However, this can lead to a high number of database calls, especially when many new entities are being persisted.

The Hi/Lo Algorithm: A Solution to the Problem

This is where the Hi/Lo algorithm comes into play. The main purpose of this algorithm is to reduce the number of database calls by generating a range of numbers for the identifiers in advance. This is achieved by using two variables: a high variable and a low variable.

The high variable is retrieved from the database sequence and represents the starting value for a range of identifiers. The low variable starts at 0 and is incremented with each generation of a new identifier until it reaches the incrementSize value. The incrementSize value is a constant that determines how many identifiers should be generated at once. Once the low variable reaches the incrementSize value, the high variable is retrieved again from the database sequence, and the low variable is reset.

Here is some pseudocode that represents the Hi/Lo algorithm:

if low < incrementSize:
    return high * incrementSize + low++
else:
    high = next value from database sequence
    low = 0
    return high * incrementSize + low++

This algorithm offers a significant performance gain as it reduces the number of database calls. Instead of making a call each time a new entity is persisted, the database is only called when a new set of identifiers is needed.

Hi/Lo in Hibernate

In Hibernate, the implementation of the Hi/Lo algorithm is part of the SequenceStyleGenerator class. To use the Hi/Lo algorithm, we need to specify the generator in our entity class with the hilo optimizer:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "hilo_sequence")
@GenericGenerator(
    name = "hilo_sequence",
    strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
    parameters = {
        @Parameter(name = "sequence_name", value = "hilo_seq"),
        @Parameter(name = "initial_value", value = "1"),
        @Parameter(name = "increment_size", value = "50"),
        @Parameter(name = "optimizer", value = "hilo")
    }
)
private Long id;

In this code example, we set the value of increment_size to 50, which means that Hibernate generates 50 IDs at once. You can adjust the value of increment_size to suit your application’s requirements. However, remember that a larger increment_size value reduces the number of database calls, but more IDs will be unused and lost upon application restarts.

Conclusion

The Hi/Lo algorithm is an efficient method for generating database identifiers in Hibernate. It reduces the number of database calls and thus improves the performance of the application. Like any technology, the Hi/Lo algorithm has its pros and cons that should be carefully weighed. But with correct configuration and use, the Hi/Lo algorithm can bring significant improvement to any Hibernate application.

Have you heard of Marcus' Backend Newsletter?

New ideas. Every week!
Top