Talking more about the allocationSize attribute in JPA

In the previous tutorials part 1 and part 2 about the @GeneratedValue annotation in JPA, I mentioned the allocationSize attribute when using the GenerationType.TABLE and GenerationType.SEQUENCE strategies. Notice that they are not detailed enough for you to understand the allocationSize attribute, so I added this article to discuss more about this attribute.

I will still take the example in the previous tutorial about @GeneratedValue annotation as an example for this tutorial.

Talking more about the allocationSize attribute in JPA

To see the effect of the allocationSize attribute, I will modify the code of the Application class a little bit like below:

As you can see, compared to the previous code, instead of just inserting a record in a transaction, I insert 5 records at a time.

Now, we will discuss the allocationSize attribute with the GenerationType.TABLE strategy first.

As you know, we have two versions to define the structure of the table containing the information that will be used to generate the value for the primary key column, depending on the value of the “hibernate.id.new.generator_mappings” property.

In case the value of this property is false, if you run the example again, you will see the following result:

Talking more about the allocationSize attribute in JPA

As you can see, the value of the id column in the clazz table is generated in a different way than the way it was generated in this tutorial.

Instead of inserting one record into the clazz table, the value of the id column of this table is increased to a number, called default allocationSize, at this time in a run with inserting 5 records, the value of the id column increases 1 unit.

What are the causes?

You already know that the column sequence_next_hi_value in the hibernate_sequences table is the column that holds the information to generate the value for the id column in the clazz table. What is the problem if every time a new record was inserted into the clazz table, you would have to query the hibernate_sequence table to retrieve the value to generate for the id column in the clazz table? The performance will be very low, right?

To solve this problem, JPA uses the term allocationSize to eliminate the need for more queries to the hibernate_sequences table.

In one application run, JPA will hold all database related information.

On the first run and insert the first record into the clazz table as shown above, the hibernate_sequences table will not have the value for the Clazz entity, the id value in the clazz table will begin with 1. At the second insert into the clazz table of this run, JPA will not query the table hibernate_sequences to get the value to generate for the id column anymore. Since the default allocation value of Hibernate is up to 32768, JPA only needs to increase the value of the id column in the clazz table by 1. So until the value of the id column in the clazz table reaches the allocationSize level, then JPA queries the hibernate_sequence table again to retrieve the new value to generate for the id column. allocationSize will not change the value so the generated values for the id column in the clazz table keep repeating until the applications turn off.

If you look at the SQL statement to the hibernate_sequences table, you will see the results for this run as follows:

Obviously, JPA only queries the hibernate_sequences table once, and since there is no record for the Clazz entity, it inserts new and updates the value for this table.

At the second run, JPA does not hold the information of the previous run, so it still queries the hibernate_sequences table to get the value to generate for the id column in the clazz table at the first insert record in the table. Then increment the value of the id column each time the new record is inserted, one by one until the allocationSize threshold is reached.

Take a look at the SQL statement for the hibernate_sequences table:

You will see the effect of the allocationSize attribute when using the customize table with the allocationSize value smaller than the default value of Hibernate.

For example, we define a customized table for the Clazz entity as follows:

Then the number of queries to the id_gen table will be greater than at the first run:

Note that we only discussed the case where the value of the “hibernate.id.new_generator_mappings” property is false.

In case the value of the “hibernate.id.new_generator_mappings” property is true, run the example again and you will see the result:

Talking more about the allocationSize attribute in JPA

Because default allocationSize in this case of Hibernate is only 1, you will see the number of times querying to default Hibernate table (hibernate_sequences) (5 times) as follows:

Now, let’s try with the customized table:

Result:

Talking more about the allocationSize attribute in JPA

The number of queries to the table id_gen will be a little bit (3 times) than the default allocationSize:

Now, let’s see how the GenerationType.SEQUENCE strategy is different.

In this case, we only consider that the value of the “hibernate.id.new_generator_mappings” property is true.

Run the example again, you will see the results as follows:

Talking more about the allocationSize attribute in JPA

And the number of queries to hibernate_sequence table will be 5 times as follows:

What about the customized table?

The results is as follows:

Talking more about the allocationSize attribute in JPA

And the number of queries to the table sequence is 3 times as follows:

BRIEFLY, as we have discussed, in the case where you use the GenerationType.TABLE and GenerationType.SEQUENCE strategies to generate values for the primary key columns in the tables in the database, the use of the allocationSize attribute should be emphasized to increase the performance for our application. The higher the value of this attribute will be higher the performance, but what the value of this attribute makes sense, that need to be considered.

Add Comment