Bonjour,
Je suis actuellement sur un problème Hibernate. Il s'agit de gérer la génération de clé primaire pour une table.
Mon besoin est le suivant, j'ai besoin :
- d'utiliser une séquence Oracle
- avoir un mécanisme performant pour récupérer des identifiants (pas d'appel à NEXTVAL dans la base à chaque insertion)
- une séquence qui peut être partagé par plusieurs applications (java et triggers)
Pour cela, je me suis tourné vers l'optimizer pooled à la place de l'optimizer hilo.
Cela permet que la séquence oracle puisse être utilisé tel quelle dans un trigger sans effectuer de calcul, contrairement à l'optimizer hilo. Comme ceci :
SELECT MA_SEQUENCE_ORACLE.NEXTVAL INTO variable FROM DUAL;
Donc pour la mise en place de mon générateur, j'ai utilisé les annotations suivantes dans mon bean Hibernate :
1 2 3 4 5 6 7 8 9 10 11
|
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "monGenerator" )
@GenericGenerator( name = "monGenerator",
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
parameters = {
@Parameter(name = "sequence_name", value = "MA_SEQUENCE_ORACLE")
, @Parameter(name = "increment_size", value = "5")
, @Parameter(name = "optimizer", value = "pooled")
}
) |
Et j'ai créé la séquence oracle suivante :
1 2 3 4 5 6 7 8
| CREATE SEQUENCE MA_SEQUENCE_ORACLE
MINVALUE 1
MAXVALUE 999999999999999999999999999
INCREMENT BY 5
NOCYCLE
NOORDER
NOCACHE
START WITH 1; |
Seulement, le comportement que j'obtiens ne correspond pas à mes attentes.
Voici un exemple du comportement que je constate.
J'ai ma séquence qui à comme nextval 1.
Je lance mon application Java avec mes annotation hibernate et celle-ci insère un élément.
J'obtiens les valeurs suivantes :
- NextVal en base : 11
- Valeur inséré : 1
J'exécute ensuite mon trigger Oracle avec la commande MA_SEQUENCE_ORACLE.NEXTVAL. J'obtiens le résultat suivant :
- NextVal en base : 16
- Valeur inséré : 11
Ensuite, mon application java ne s'est pas arrêtée et elle essaye d'insérer 5 valeurs en base et j'obtiens une erreur car la clé primaire n'est pas respecté :
- NextVal en base : 21
- Valeurs insérés avec succès : 2, 3, 4, 5
- Valeur rejeté : 11
Je ne comprends pas pourquoi l'optimizer pooled utilise un identifiant déjà utilsé par le trigger.
Avez-vous une idée du pourquoi de ce fonctionnement? Est-ce que j'utilise mal la séquence?
Cordialement.
Partager