Frage

Im Grunde möchte ich eine Art und Weise Sequenzwerte in einer Datenbank neutral zuzugreifen. Der Anwendungsfall ist, dass ich ein Feld für eine Entität, die ich (anders als die id) auf der Grundlage eines Inkrementieren Wert festlegen möchten.

Zum Beispiel, sagen, dass ich eine Shipment Einheit haben. Irgendwann nach der Sendung erstellt wird, wird es ausgeliefert. Sobald es ausgeliefert wird, ist eine offensichtliche Nummer für sie erzeugt und zugeordnet. Die Manifest-Nummer sieht etwa so M000009 (Wo das Zeug nach dem ‚M‘ ist ein links gepolsterter Wert aus einer Sequenz).

Etwas ähnlich hier gefragt bei SO , aber ich bin kein Fan von der Lösung, da sie eine andere Tabelle zu halten erfordert und scheint wie eine seltsame Beziehung zu haben.

Wer weiß, ob es möglich ist, so etwas wie Hibernate MultipleHiLoPerTableGenerator als etwas anderes als ein ID-Generator zu benutzen?

Wenn das nicht möglich ist, weiß jemand von irgendwelchen Bibliotheken, die diese handhaben (entweder Hibernate oder sogar nur reine JDBC). Ich würde es vorziehen, nicht zu haben, dies selbst zu schreiben (und haben mit Prefetching Werten umgehen, Sperren und Synchronisation).

Danke.

War es hilfreich?

Lösung

Ich denke, die Komplexität Ihrer Aufgabe abhängt, ob Sie manifestieren Zahl muss sequenzielle sein:

  • Wenn Sie nicht sequenzielle manifest Zahlen brauchen dann glückliche Tage es ist und eine Sequenz verwenden kann.
  • Wenn Sie sequenzielle manifest Zahlen tun müssen (oder Ihre Datenbank unterstützt keine Sequenzen) dann eine ID-Tabelle mit dem entsprechenden Sperr verwenden, so dass jede Transaktion einen eindeutigen Wert in der Folge bekommt.

Dann haben Sie zwei Möglichkeiten, die ich mir vorstellen kann:

  • schreiben den notwendigen JDBC-Code auf Ihrem Client, um sicherzustellen, (wenn die manifest Zahl sequentiell ist), dass die Transaktion, dass das gleiche verwendet wird für das Datenbank-Update ist.
  • einen Trigger verwenden, um die Manifest-Nummer zu erstellen, wenn das entsprechende Update auftritt.

ich glaube, meine Präferenz der Auslöser sein würde, da die Transaktion Seite der Dinge würde gesorgt werden, obwohl es das Objekt bedeuten würde, auf dem Client müßte erfrischend.

Andere Tipps

Ich habe nicht gelesen, die verknüpfte ähnliche Lösung über, aber klingt wie etwas, das ich tun aufgespult. Ich habe eine Tabelle nur für Sequenzen. Ich habe eine Reihe in der Tabelle für jede Sequenz-Typ I benötigt wird.

Ich hatte dann eine Sequenz-Generator-Klasse, die die notwendige SQL-Abfrage tun würde den Sequenzwert für eine bestimmte benannte Sequenz zu holen und zu aktualisieren.

habe ich Hibernate Dialect Klasse es in einer db neutral zu tun.

Ich würde auch ‚Cache‘ die Sequenzen. Ich würde die gespeicherte Sequenzwert durch eine große Zahl stoßen, und dann diejenigen, die ihm zugewiesenen Sequenzen aus meinem Generator Klasse austeilen. Wenn die Klasse zerstört wurde (dh. App Shutdown), wäre eine neue Instanz des Sequenzgenerators auf dem gespeicherten Wert gestartet. (Eine Lücke in meinen Sequenznummern, die keine Rolle)

Hier ist ein Code samnple. Ich möchte dies mit Caveat - Ich habe nicht comiled und es reuires Federcode. Nachdem dies gesagt ist es sollte noch die Knochen von dem, was Sie tun möchten.

public Long getManifestNumber() {
        final Object result = getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session sess) throws HibernateException, SQLException { 
                SQLQuery sqlQuery = sess.createSQLQuery("select MY_SEQUENCE.NEXTVAL from dual");
                sqlQuery.uniqueResult();
            }
        });
        Long toReturn;
        if (result instanceof BigDecimal) {
            toReturn = ((BigDecimal)result).longValue();
        }
        return toReturn;
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top