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 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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.