JPA hibernate @GeneratedValue with sequence on Oracle

When using Oracle, the JPA with hibernate implementation on the @GeneratedValue with sequence would be quite tricky. I am trying to make a summary here. The version used are JPA 2.1 and Hibernate 4.3.11.Final

Default generator setting

@GeneratedValue with strategy AUTO and default allocationSize(50)

This will use the ‘org.hibernate.id.SequenceGenerator’ which will get a SEQ+1 value.

@GeneratedValue with strategy SEQUNCE and default allocationSize(50)

This will use the ‘org.hibernate.id.SequenceHiLoGenerator’ because the maxLo value in this class is 49 which is due to the default allocationSize 50,  which will return a SEQ*50 value.

@GeneratedValue with strategy AUTO and allocationSize=1

This would have the same behavior with the default allocationSize using ‘org.hibernate.id.SequenceGenerator’, which gives SEQ+1

@GeneratedValue with strategy SEQUNCE and default allocationSize=1

This would use the ‘org.hibernate.id.SequenceHiLoGenerator’, but since we set the allocationSize to 1, it would not use the HiLo optimizer but delegate the work to the ‘SequenceGenerator’, so we will get the same SEQ+1 value.

 

hibernate.id.new_generator_mappings set to true

@GeneratedValue with strategy AUTO/SEQUNCE and default allocationSize(50)

This will use ‘org.hibernate.id.enhanced.SequenceStyleGenerator’ which will subtract the current sequence with allocationSize. so we get the value: SEQ-49

@GeneratedValue with strategy AUTO/SEQUNCE and default allocationSize=1

This would also use the ‘org.hibernate.id.enhanced.SequenceStyleGenerator’ but since we assigned the allocationSize to 1, it would return the regular SEQ+1 value.

 

Summary

As we can see the inconsistency behaviors above, the best way IMO is to set the new ‘hibernate.id.new_generator_mappings’ to true to leverage the new ‘SequenceStyleGenerator’ where we have the flexibility to use regular sequence but also could bump up sequence value with larger allocationSize if we need to persist a lot of entities at one time. The only thing we need to pay attention is to not forget to have allocationSize=1 to the existing annotation.

If we set this attribute to TRUE, For the existing entities using HiLo generator, we could either 1. bump up the sequence, add allocationSize to 50 OR 2. use @GenericGenerator annotation to still use SequenceHiLoGenerator.

    @GenericGenerator(name = "RPT_QMRC_SCRT_PRDCT_6_ID_GEN", strategy = "org.hibernate.id.SequenceHiLoGenerator",
        parameters =  {@Parameter(name = "sequence", value = "SEQ_RPT_QMRC_SCRT_PRDCT_6_ID"), @Parameter(name = "max_lo", value = "50")})
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "RPT_QMRC_SCRT_PRDCT_6_ID_GEN")
    @Column(name = "RPT_QMRC_SCRT_PRDCT_6_ID", nullable = false, insertable = true, updatable = true)
    public Long getRptQmrcScrtPrdct6Id()
    {
        return rptQmrcScrtPrdct6Id;
    }
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s