J'ai configuré hibernate pour utiliser la séquence Oracle. La séquence est créée avec cache = 20, incrément = 1.
Tout fonctionne bien, hiberner les entités persistantes. La valeur id est étrange: 50,51 ... 76 201,202 ... 209,1008,1009,5129,5130 ....
Si je demande une valeur de séquence (sélectionnez hibernate_sequence.nextval parmi dual), je reçois une valeur de 2,3,4 ...
Si j'active le débogage hibernate sql, il est parfois procédé à l'appel "select hibernate_sequence.nextval from dual", mais le numéro attribué par hibernate à ID ne transmet pas la séquence!
@Id
@Column(name = "ID", insertable = false, updatable = false)
@SequenceGenerator(name = "SequenceIdGenerator", sequenceName = "HIBERNATE_SEQUENCE")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SequenceIdGenerator")
private Long id;
En effet, SequenceGenerator n'est pas vraiment un générateur de séquence. C'est un générateur de séquence hi-lo. Cela signifie que lors de son premier appel, il obtient la valeur suivante de la séquence (6 par exemple), puis multiplie cette valeur par 50 et vous donne le résultat (300). La prochaine fois qu'il est appelé, il retourne 301 (sans passer à la séquence), et ainsi de suite jusqu'à atteindre 349. Ensuite, il demande à la séquence la valeur suivante et obtient 7, qu'il multiplie par 50 et donne à nouveau 350. Mon La description de l'algorithme peut être décalée de un, mais vous voyez l'idée.
Si vous arrêtez et démarrez votre application, il y aura donc des lacunes. Mais il est plus efficace qu'un générateur de séquence pur, car il effectue un appel de base de données une fois sur 50 générations.
Voir http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#mapping-declaration-id-enhanced-optimizers et http: //docs.jboss. org/hibernate/core/3.6/reference/fr-US/html_single/# mapping-declaration-id-generator pour plus de détails.
Je suppose que votre question est que les valeurs de la colonne ID dans la base de données ne sont pas une séquence naturelle, mais pourquoi vous voyez des lacunes:
Un peu de fond:
select HIBERNATE_SEQUENCE.nextval from DUAL
, la valeur de la séquence est augmentée.Par exemple, considérons le scénario suivant:
Vous avez deux entités Entity1 et Entity2 utilisant HIBERNATE_SEQUENCE en tant que générateur d'identifiant:
select HIBERNATE_SEQUENCE.nextval from DUAL
(renvoie 104)Donc à la fin, vous aurez:
ce qui explique les lacunes.
MODIFIER:
Même si le @SequenceGenerator était configuré pour utiliser le SequenceGenerator
au lieu du SequenceHiLoGenerator
(comme l'a souligné JB Nizet, ce qui est une meilleure explication des lacunes), les lacunes dans les ID générés par les séquences sont courantes.
CREATE SEQUENCE SEQ_SEQUENCENAME INCREMENT BY 1 START WITH 1 MINVALUE 1;
grant all on SEQ_SEQUENCENAME to public;
@Id
@Column(name = "ID", unique = true, nullable = false)
@SequenceGenerator(name = "SequenceIdGenerator", sequenceName = "SEQ_SEQUENCENAME")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SequenceIdGenerator")
private int Id;