I have configured hibernate to use oracle sequence. Sequence is created with cache=20, increment=1.
All works fine, hibernate persisting entities. The id value is strange: 50,51....76,201,202...209,1008,1009,5129,5130 ....
If I ask for sequence value (select hibernate_sequence.nextval from dual) I get value like 2,3,4 ....
If I turn on hibernate sql debug, there is time to time call "select hibernate_sequence.nextval from dual" but number assigned by hibernate to ID doesn't relay on sequence!
@Id @Column(name = "ID", insertable = false, updatable = false) @SequenceGenerator(name = "SequenceIdGenerator", sequenceName = "HIBERNATE_SEQUENCE") @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SequenceIdGenerator") private Long id;
Hibernate uses a generic sequence. But if you need a sequence that will be used in a script of SQL and also in Hibernate create the sequence as we said. there is another annotation GenericGenerator: (sequence_name -should be like this!) You should use one of the following @SequenceGenerator OR @GenericGenerator.
IDENTITY: Hibernate relies on an auto-incremented database column to generate the primary key, SEQUENCE: Hibernate requests the primary key value from a database sequence, TABLE: Hibernate uses a database table to simulate a sequence.
SEQUENCE Generation. To use a sequence-based id, Hibernate provides the SequenceStyleGenerator class. This generator uses sequences if our database supports them. It switches to table generation if they aren't supported.
ORA-02289: sequence does not exist. Cause: The specified sequence does not exist, or the user does not have the required privilege to perform this operation. Action: Make sure the sequence name is correct, and that you have the right to perform the desired operation on this sequence.
This is because the SequenceGenerator is not really a sequence generator. It's a sequence hi-lo generator. This means that the first time it's invoked, it gets the next value from the sequence (6 for example), then multiplies this value by 50 and gives you the result (300). The next time it's invoked, it returns 301 (without going to the sequence), and so on until it reaches 349. Then it asks the sequence for the next value and obtains 7, which it multiplies by 50 again to give you 350. My algorithm description could be off by one, but you get the idea.
If you stop and start your application, it will thus have gaps. But it's more efficient than a pure sequence generator because it only makes a database call once in 50 generations.
See http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#mapping-declaration-id-enhanced-optimizers and http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#mapping-declaration-id-generator for details.
I take it that your question is that the values of the ID column in the database are not a natural sequence, but why you are seeing gaps:
A bit of background:
select HIBERNATE_SEQUENCE.nextval from DUAL
the value of the sequence is increased.For example, consider the following scenario:
You've got two entities Entity1 and Entity2 using HIBERNATE_SEQUENCE as the ID generator:
select HIBERNATE_SEQUENCE.nextval from DUAL
(returns 104)So at the end of it you'll have:
which explains the gaps.
EDIT:
Even if the @SequenceGenerator were setup to use the SequenceGenerator
rather than the SequenceHiLoGenerator
(as pointed out by JB Nizet, which I think is a better explanation for the gaps), gaps in IDs generated by sequences are a common occurrence.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With