it-swarm.com.de

Wie verwendet man eine vorhandene Oracle-Sequenz, um eine ID im Ruhezustand zu generieren?

Ich habe eine ältere Oracle-Datenbank mit einer Sequenz namens PRODUCT_ID_SEQ

Hier ist das Mapping der Product-Klasse, für die ich korrekte IDs generieren muss:

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

   ...
}

Es sieht jedoch so aus, als würden ids mit einem Intervall von 50 generiert (z. B. 1000, 1050, 1100 usw.). Dies entspricht dem Standardwert von allocationSize property = 50. Das bedeutet, dass Hibernate die in der bereits definierten Sequenz nicht wirklich verwendet db. 

Wie kann ich den Ruhezustand dazu verwenden, die Sequenz zu verwenden?

24
Vladimir

Die Antwort auf die ursprüngliche Frage:

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

Es ist allocationSize, das den Wert auf inkrementiert.

24
Mike Demenok

Ich bin es nicht gewohnt, Annotationen zu verwenden. Das habe ich in meiner * .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>

Sie können dies problemlos Anmerkungen zuordnen. Der Generator Sequenzidentität verwendet das automatische Inkrementieren mit Sequenzen.

17
rsilva4

Hier ein Arbeitsbeispiel mit Annotationen. Auf diese Weise wird die vorhandene DB-Sequenz verwendet (Sie können auch die "Sequenz" -Strategie verwenden, jedoch mit weniger Leistung beim Einfügen):

@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
Tristan

Erstellen Sie Ihren Sequenznamen in Oracle, z. B. contact_seq . In Ihrer POJO-Klasse. Definieren Sie die folgende Annotation für Ihre Sequenz. 

@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_seq_gen")
@SequenceGenerator(name="my_seq_gen", sequenceName="contacts_seq")
5
user1256936

Ich hatte das gleiche Problem beim Upgrade von 3.5.5 auf 5.0.6.Final.

Ich habe es gelöst, indem ich das Mapping in der HBM-Datei neu konfiguriert habe:

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

zu: 

    <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
jvergara

Wenn Sie javax.persistence.SequenceGenerator verwenden, verwenden Sie für den Ruhezustand hilo und erzeugen möglicherweise große Lücken in der Sequenz. Es gibt einen Beitrag, der sich mit diesem Problem befasst: https://forum.hibernate.org/viewtopic.php?t=973682

es gibt zwei Möglichkeiten, dieses Problem zu beheben

  1. Fügen Sie in der Annotation von SequenceGenerator AllocationSize = 1, initialValue = 1 hinzu

  2. verwenden Sie statt javax.persistence.SequenceGenerator org.hibernate.annotations wie folgt:

    @ javax.persistence.SequenceGenerator (name = "Frage_id_sequenz", sequenceName = "S_QUESTION")

    @ org.hibernate.annotations.GenericGenerator (name = "Frage_id_sequenz", strategie = "folge", parameter = {@Parameter (name = "folge", wert = "S_QUESTION")})

Ich habe beide Möglichkeiten getestet, was gut funktioniert.

4
Maninder

AllocationSize und incrementBy sind völlig unterschiedliche Dinge.

Der Ruhezustand verwendet natürlich Ihre in DB erstellte Sequenz, aber abhängig von AllocationSize können Sie eine Lücke im generierten Wert finden.

Zum Beispiel - Angenommen, der aktuelle Sequenzwert ist 5, Inkrementierung um 1 in db und AllocationSize default 50.

Jetzt möchten Sie eine Sammlung von 3 Elementen über Hibernate speichern. Anschließend wird Hibernate weist die generierte ID 250, 251, 252 zu

Dies ist zu Optimierungszwecken. Der Ruhezustand muss nicht zu db zurückgehen und den nächsten inkrementierten Wert abrufen.

Wenn Sie dies nicht möchten, können Sie allocationSize = 1 als bereits beantwortete Einstellung festlegen

2
shakhawat

Ich benutze folgendes auf PostgreSQL und funktioniert gut.

 @Id
 @GeneratedValue(generator = "my_gen")
 @SequenceGenerator(name = "my_gen", sequenceName = "my_seq_in_db")
 private int userId;
1
Summer

Erstens: Sie sollten in Ihrer Datenbank die Reihenfolge wie folgt erstellen: 

CREATE SEQUENCE  "PRODUCT_ID_SEQ"  MINVALUE 0 MAXVALUE 1000000000 INCREMENT BY 1 START WITH 1 CACHE 500 NOORDER  NOCYCLE ;

und in Ihrer Datei Product.hbm.xml Konfiguration machen Sie: 

 <class name="ProductPersistant" table="Product">

    <id  name="id"  type="Java.lang.Long" column="productID" >
          <generator class="sequence"> 
               <param name="sequence">PRODUCT_ID_SEQ</param>   
          </generator>
    </id>
0


Hibernate verwendet standardmäßig den Sequenz-HiLo-Generator, der, sofern Sie keine besonderen Anforderungen haben, gut ist (in Bezug auf die Leistung). Sie können mehr darüber in meinem Blog lesen hier

Eyal

0
Eyal Lupu