Comment utiliser la séquence Oracle existante pour générer des id en hibernation?

j'ai legacy Oracle db avec une séquence nommée PRODUCT_ID_SEQ.

voici le mappage de Product classe pour laquelle j'ai besoin de générer corriger id:

public class Product {
   @GeneratedValue(strategy = GenerationType.SEQUENCE, 
                       generator = "retailerRaw_seq")
   @SequenceGenerator(name = "retailerRaw_seq", 
                      sequenceName = "PRODUCT_ID_SEQ")
   private Long id;

   ...
}

mais on dirait que les ids sont générés avec un intervalle de 50, comme 1000, 1050,1100 etc. Cela correspond à la valeur par défaut de allocationSize propriété = 50. Donc cela signifie que L'hibernation N'utilise pas réellement la séquence qui est déjà définie dans le db.

Comment puis-je faire Hibernate utiliser le séquence?

24
demandé sur RubioRic 2010-01-28 17:59:28

9 réponses

La réponse à la question initiale:

@SequenceGenerator(name="EL_SEQ", sequenceName="EL_SEQ",allocationSize=1)

C'est allocationSize qui définit la valeur d'incrémentation.

24
répondu Mike Demenok 2011-10-24 23:13:36

je n'ai pas l'habitude d'utiliser des annotations, c'est ce que j'ai dans mon *.hbm.xml:

<id name="id" type="java.lang.Integer">
    <column name="ID_PRODUCT" />
    <generator class="sequence-identity" >
        <param name="sequence">PRODUCT_ID_SEQ</param>
    </generator>
</id>

Vous pouvez facilement faire correspondre cela aux annotations. Le générateur séquence d'identité utilise l'incrément automatique avec les séquences.

17
répondu rsilva4 2010-01-28 15:28:38

voici un exemple de travail avec annotations, de cette façon, la séquence DB existante sera utilisée (Vous pouvez également utiliser la stratégie "séquence", mais avec moins de performances lors de l'insertion):

@Entity
@Table(name = "USER")
public class User {

    // (...)

    @GenericGenerator(name = "generator", strategy = "sequence-identity", parameters = @Parameter(name = "sequence", value = "USER_SEQ"))
    @Id
    @GeneratedValue(generator = "generator")
    @Column(name = "ID", unique = true, nullable = false, precision = 22, scale = 0)
    public Long getId() {
        return this.id;
    }
8
répondu Tristan 2011-08-14 08:43:37

créez votre nom de séquence dans Oracle, par exemple, contacts_seq. Dans ton cours de POJO . Définir l'annotation suivante pour votre séquence.

@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_seq_gen")
@SequenceGenerator(name="my_seq_gen", sequenceName="contacts_seq")
5
répondu user1256936 2015-12-23 14:10:20

j'ai eu le même problème en passant de 3.5.5 à 5.0.6.Final.

Je l'ai résolu en reconfigurant le mapping dans le fichier HBM à partir de:

    <generator class="sequence">
        <param name="sequence">PRODUCT_ID_SEQ</param>
    </generator>

à:

    <generator class="org.hibernate.id.enhanced.SequenceStyleGenerator"> 
        <param name="prefer_sequence_per_entity">true</param> 
        <param name="optimizer">none</param>
        <param name="increment_size">1</param>
        <param name="sequence_name">PRODUCT_ID_SEQ</param>
    </generator>
5
répondu jvergara 2015-12-27 22:57:04

Si vous utilisez javax.persistance.Séquencegenerator, hibernation utiliser hilo et peut-être créer de grandes lacunes dans la séquence. Il y a un post traitant de ce problème:https://forum.hibernate.org/viewtopic.php?t=973682

il y a deux façons de résoudre ce problème

  1. dans L'annotation SequenceGenerator, ajouter allocationSize = 1, initialValue= 1

  2. au lieu d'utiliser javax.persistance.Séquencegenerator, utiliser org.hiberner.les annotations, comme ceci:

    @javax.persistance.SequenceGenerator (name = "Question_id_sequence", sequenceName = "S_QUESTION")

    @org.hiberner.annotation.GenericGenerator(name="Question_id_sequence", de la stratégie = "sequence", parameters = { @Paramètre(nom="sequence", value="S_QUESTION") } )

j'ai testé les deux façons, qui fonctionne très bien.

4
répondu Maninder 2013-09-10 13:43:46

j'utilise le suivi sur PostgreSQL et fonctionne très bien.

 @Id
 @GeneratedValue(generator = "my_gen")
 @SequenceGenerator(name = "my_gen", sequenceName = "my_seq_in_db")
 private int userId;
2
répondu Summer 2014-02-25 12:32:04

allocationSize et incrementBy sont des choses complètement différentes.

Hibernate est bien sûr en utilisant votre séquence créée en DB mais en fonction de allocationSize vous pouvez trouver gap dans la valeur générée.

Par exemple- Supposons que la valeur de la séquence courante est 5,incrément de 1 db et allocationSize par défaut 50.

Maintenant vous voulez sauver une collection de 3 éléments par hibernation, puis Hibernate va attribuer des id généré 250, 251, 252

ceci est dans un but d'optimisation. L'hibernation n'a pas à retourner à la base de données et chercher la valeur incrémentée suivante.

Si vous ne voulez pas que cela viens de la configuration de allocationSize = 1 comme déjà répondu fera l'objet

2
répondu shakhawat 2016-05-25 09:19:31



Par défaut Hibernate utilise sequence HiLo generator qui, sauf si vous avez des besoins spéciaux, il est bon (la performance sage). Vous pouvez lire la suite de ce sujet dans mon blog ici

Eyal

0
répondu Eyal Lupu 2011-05-09 11:19:38