javaoracle-databasespring-boothibernatesequence-generators

Old hibernate hilogenerator to @TableGenerator use different start id's


I'm migrating a spring boot 2 application to spring boot 2

In the old application I have a MultipleHiLoPerTableGenerator (SB2, J11). This one is removed. I migrated to the @TableGenerator .

 @GenericGenerator(name = "tk_sequence",
        parameters = {
                @org.hibernate.annotations.Parameter(name = "table", value = "hibernate_seq"),
                @org.hibernate.annotations.Parameter(name = "primary_key_column", value = "seq_name"),
                @org.hibernate.annotations.Parameter(name = "primary_key_value", value = "seq_token"),
                @org.hibernate.annotations.Parameter(name = "value_column", value = "seq_value"),
                @org.hibernate.annotations.Parameter(name = "max_lo", value = "49"), // 0-49 = 50 numbers
        },
        strategy = "....MultipleHiLoPerTableGenerator"
)

In the new application (SB3, J17) I have:

@TableGenerator(name = "tk_sequence", table = "hibernate_seq", pkColumnName = "seq_name",
        pkColumnValue = "seq_token", valueColumnName = "seq_value", allocationSize = 50, initialValue = 0)

and property

spring.jpa.properties.hibernate.id.optimizer.pooled.preferred=hilo

This works, with one exception: The inital id's are different old seq generator: 0-49, 50-99, etc. new seq generator: 1-50, 51-100, etc.

This will give duplicate id issues. Since multiple applications are writing to the dabase, we cannot change the behaviour. Until we are ready to migrate all other applications, we need the same sequence generator.

Database is oracle database.

How do I solve this problem?

Edit 1:

I switched to using legacy-hilo (as is used in the MultipleHiLoPerTableGenerator). However the TableGenerator class reads the value from the table, increments it, and uses it. The old MultipleHiLoPerTableGenerator reads the value from the table, uses it, then increments it. Resulting in different sequences being used for the same value.

So I still don't have an implementation that uses the same sequence generation


Solution

  • The solution:

    Hibernate has changed it's behaviour from reading and using the value between hibernate 5 & 6.

    To get the old behaviour back, you can set the following property:

    hibernate.id.generator.stored_last_used=false
    

    Then use the legacy-hilo generator

    spring.jpa.properties.hibernate.id.optimizer.pooled.preferred=legacy-hilo
    

    In that way hibernate will generate the id's just like MultipleHiLoPerTableGenerator.

    These properties are very hidden in the documentation and not very clear from the code. You can find them here: https://docs.jboss.org/hibernate/orm/6.2/javadocs/org/hibernate/cfg/AvailableSettings.html#TABLE_GENERATOR_STORE_LAST_USED