oraclespring-boothibernatejpa

Why Hibernate 6.X creates HTE_ temporary tables when allocationSize is greater then 1?


I am updating my application, that uses Oracle database, from Spring Boot 2.7 to Spring Boot 3.3. In my entities, I have several @SequenceGenerator specified as the following:

    @Id
    @GeneratedValue(generator = "LABEL_SEQ")
    @SequenceGenerator(name = "LABEL_SEQ", sequenceName = "LABEL_SEQ")
    private Long id;

i.e, the default allocationSize=50 is being used.

This makes Hibernate set the variable needsMultiTableInsert to true, as the fragment of Hibernate code shows

        if ( !needsMultiTableInsert && getGenerator() instanceof BulkInsertionCapableIdentifierGenerator ) {
            if ( getGenerator() instanceof OptimizableGenerator ) {
                final Optimizer optimizer = ( (OptimizableGenerator) getGenerator() ).getOptimizer();
                needsMultiTableInsert = optimizer != null && optimizer.getIncrementSize() > 1;
            }
        }

Because of that, Hibernate creates the table HTE_LABEL and a bunch of temporary tables for the other entities, that I do not know if are really useful and pollute my database management.

I verified that setting the properties:

spring.jpa.properties.hibernate.query.mutation_strategy.global_temporary.create_tables=false
spring.jpa.properties.hibernate.query.mutation_strategy.global_temporary.drop_tables=false

avoids the creation of HTE_ tables. But my question is why the allocationSize > 1 implies in multi table inserts? Will those multi table inserts be executed by Hibernate regardless of the code of my application? If not, how can I verify that my application does not imply any multi table insert and then I can safely use the above properties to block the creation of temporary tables?


Solution

  • When allocationSize > 1, Hibernate uses an optimizer that pre-allocates a block of IDs to reduce the number of sequence queries to the database. This optimization assumes that batch inserts or multi-table inserts might be required to handle the bulk allocation efficiently. Therefore, Hibernate sets needsMultiTableInsert = true to prepare for potential multi-table insert operations, even if your application does not explicitly perform them. This leads to the creation of HTE_ temporary tables.

    To prevent the creation of HTE_ temporary tables, you should disable the bulk allocation optimization and turn off the properties for temporary table creation and drop strategies:

    @Id
    @GeneratedValue(generator = "LABEL_SEQ")
    @SequenceGenerator(name = "LABEL_SEQ", sequenceName = "LABEL_SEQ", allocationSize = 1)
    private Long id;
    

    and:

    spring.jpa.properties.hibernate.query.mutation_strategy.global_temporary.create_tables=false
    spring.jpa.properties.hibernate.query.mutation_strategy.global_temporary.drop_tables=false