2013-08-27 7 views
13

Ich habe ein Problem, das ich nicht verstehen kann. In Hibernate habe ich kein Problem mit dem folgenden:EclipseLink und Sequence Generator Vorbelegung

@GeneratedValue(strategy = GenerationType.AUTO, generator = "email-seq-gen") 
@SequenceGenerator(name="email-seq-gen", sequenceName="EMAIL_SEQ_GEN", allocationSize=500) 

Da ist in meinem schema.ddl Ich habe dies:

CREATE SEQUENCE EMAIL_SEQ_GEN START 1 INCREMENT 500; 

nicht viel zu sehen. Alles funktioniert wie erwartet. Allerdings, wenn ich meinen Provider zu Eclipse wechseln bekomme ich diesen Fehler:

The sequence named [EMAIL_SEQ_GEN] is setup incorrectly. Its increment does not match its pre-allocation size. 

Also ich natürlich google um und sehe, etwas über Eclipse eine negative Zahl zu schaffen, wenn der Anfangswert 1 ist und dass es die allocationSize gleich.

Also, okay, das Hinzufügen so „Anfangswert = 500“ und meinen DDL-Skripte Update auf „START 500“ korrigiert diese Fehler, aber jetzt meine Nummerierung beginnt bei 500 statt 1. Was soll das? Ist das ein EclipseLink-Bug oder gibt es etwas, das ich nicht verstehe? Ich möchte Sequenzen erzeugen, die bei 1 beginnen und Zuweisungsgrößen haben, die auf die Entity abgestimmt sind (in diesem Fall 500). Wie würde ich das mit EclipseLink machen?

Danke!

CREATE SEQUENCE EMAIL_SEQ_GEN START 1 INCREMENT 500; 

Was ist der richtige Weg, um meine Einheit zu annotieren es mit Eclipselink zu verwenden:

Ein anderer Weg, dies zu fragen ist .... diese DDL gegeben?

Wenn ich lasse Eclipse meine DDL erzeugt dann die:

@GeneratedValue(strategy = GenerationType.AUTO, generator = "email-seq-gen") 
@SequenceGenerator(name="email-seq-gen", sequenceName="EMAIL_SEQ_GEN", initialValue=1, allocationSize=500) 

Werden diese erzeugen:

CREATE SEQUENCE EMAIL_SEQ_GEN INCREMENT BY 500 START WITH 500; 

Welche Art impliziert, dass es unmöglich ist, eine DDL mit einem „START MIT 1 zu erstellen "mit EclipseLink.

+0

Wenn Sie die andere Richtung gehen (lassen Sie EclipseLink die DDL von Ihren Entitäten erzeugen), was erzeugt es? – DannyMo

+0

Ich habe den ursprünglichen Post editiert, um die Antwort auf Ihre Frage hinzuzufügen. –

Antwort

18

Standardmäßig verwenden mit @SequenceGenerator gekennzeichnete Entities initialValue = 1 und alocationSize = 50.

public @interface SequenceGenerator { 
    /** 
    * (Optional) The value from which the sequence object 
    * is to start generating. 
    */ 
    int initialValue() default 1; 

    /** 
    * (Optional) The amount to increment by when allocating 
    * sequence numbers from the sequence. 
    */ 
    int allocationSize() default 50; 
} 

A "sequential" Entity-ID scheint von Eclipse mit der folgenden Formel berechnet werden:

entityId = initialValue - allocationSize + INCREMENT_BY 

oder bei DDL mit:

entityId = START_WITH - allocationSize + INCREMENT_BY 

zurück auf Ihre Unterhaltung Fälle:


@SequenceGenerator( 
    name="email-seq-gen", 
    sequenceName="EMAIL_SEQ_GEN", 
    allocationSize=500 
) // initialValue=1 (default) 

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 1 INCREMENT BY 500; 

produziert

entityId = 1 - 500 + 1 = -500 // EclipseLink error 

@SequenceGenerator( 
    name="email-seq-gen", 
    sequenceName="EMAIL_SEQ_GEN", 
    initialValue=1, 
    allocationSize=500) 

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 1 INCREMENT BY 500; 

produziert

entityId = 1 - 500 + 1 = -500 // EclipseLink error 

@SequenceGenerator( 
    name="email-seq-gen", 
    sequenceName="EMAIL_SEQ_GEN", 
    initialValue=500, 
    allocationSize=500 
) 

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 500 INCREMENT BY 500; 

produziert
entityId = 500 - 500 + 500 = 500 // fine, but inappropriate 
entityId = 500 - 500 + 1000 = 1000 // incremented by 500 
entityId = 500 - 500 + 1500 = 1500 // incremented by 500 
... 

Um Ihre Anforderungen an die folgenden Voraussetzungen erfüllen ein verwendet werden soll:

@SequenceGenerator( 
    name="email-seq-gen", 
    sequenceName="EMAIL_SEQ_GEN", 
    allocationSize=500 
) // initialValue=1 (default) but 'START WITH'=500 

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 500 INCREMENT BY 1; 

produziert

entityId = 500 - 500 + 1 = 1 
entityId = 500 - 500 + 2 = 2 
entityId = 500 - 500 + 3 = 3 
... 

Eine bestehende Sequenz kann aus der zugrunde liegenden Datenbank mit der folgenden entfernt werden SQL command:

DROP SEQUENCE email_seq_gen RESTRICT; 

Ich hoffe, es hilft.

+0

Es wäre schön zu wissen, wie man erstellte Sequenzen löscht/löscht. Ich habe mehrere Ansätze ausprobiert, aber keiner von ihnen funktioniert. – burseaner

+0

@ burseaner: Ich habe einen Befehl hinzugefügt, der eine existierende Sequenz löscht. – wypieprz

+1

Das Erstellen der Sequenz mit Inkrement 1 ist falsch. EclipseLink ruft die Sequenz nur einmal pro Zuweisungs-Batch auf (in diesem Fall einmal für jeweils 500 Entitäten, die in derselben Transaktion hinzugefügt wurden). Daher muss das Inkrement gleich 500 sein. Ja, Zahlen werden übersprungen, wenn ein Zuweisungs-Batch kleiner als 500 ist, aber das ist der Preis, den Sie für die Effizienz zahlen, dank weniger Aufrufen der Sequenz. Um den aufgetretenen Fehler zu sehen, fügen Sie zwei Entitäten hinzu, beenden Sie das Java-Programm und fügen Sie eine weitere Entität hinzu. Eine java.sql.SQLIntegrityConstraintViolationException wird aufgrund einer doppelten ID auftreten. – bgh

2

Ihre Sequenz bei 500 1 nicht starten sollte Wenn Sie bei 1 beginnen, dann die erste nextval geben Sie nur 1-ID statt 500.

Ansonsten auf der Sequenz rufen nextval, nachdem es die Einrichtung, so dass es wird zu 501.

Ist der Fehler eine Warnung oder ein Fehler? Wenn du es einfach ignorierst, funktioniert es immer noch?

+1

Wie macht das Sinn? Wenn ich Code zum Poolen von Identitäten schreibe, bekomme ich 1, 501, 1001 und so weiter. Das bekomme ich auch von Hibernate? Wenn dies bei EclipseLink nicht der Fall ist und (aus dem Google-Umfeld) scheint es, dass viele ein Problem damit hatten, warum reparieren sie nicht einfach diesen Algorithmus? –

+0

Oh, und es ist ein Fehler, keine Warnung. –