The Hi/Lo Algorithm in Hibernate: Optimizing Database Identifier Generation
Author
Marcus HeldIn 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.