Frage

gibt es eine Lösung für Batch-Einsatz über Hibernate in partitionierten postgresql Tabelle? momentan bin ich einen Fehler wie diese bekommen ...

ERROR org.hibernate.jdbc.AbstractBatcher - Exception executing batch:
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
   at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:61)
   at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46)
   at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:68)....

Ich habe diesen Link http: // Listen. jboss.org/pipermail/hibernate-dev/2007-October/002771.html aber ich kann nicht überall im Web ist dieses Problem gelöst oder wie es sein kann, umgehen

finden
War es hilfreich?

Lösung

Sie können mit einem benutzerdefinierten Dosierer, indem der hibernate.jdbc.factory_class Eigenschaft ausprobieren möchten. Sicherzustellen, überwintern die Aktualisierungszählwert von Batch-Operationen nicht überprüfen kann Ihr Problem beheben, können Sie das erreichen, indem Sie Ihre individuelle Dosierer die Klasse BatchingBatcher erweitern, und dann das Überschreiben der Methode doExecuteBatch (...), um wie folgt aussehen:

    @Override
    protected void doExecuteBatch(PreparedStatement ps) throws SQLException, HibernateException {
        if ( batchSize == 0 ) {
            log.debug( "no batched statements to execute" );
        }
        else {
            if ( log.isDebugEnabled() ) {
                log.debug( "Executing batch size: " + batchSize );
            }

            try {
//              checkRowCounts( ps.executeBatch(), ps );
                ps.executeBatch();
            }
            catch (RuntimeException re) {
                log.error( "Exception executing batch: ", re );
                throw re;
            }
            finally {
                batchSize = 0;
            }

        }

    }

Beachten Sie, dass die neue Methode die Ergebnisse nicht überprüfen Sie die vorbereiteten Anweisungen auszuführen. Beachten Sie, dass diese Änderung könnte Auswirkungen auf Hibernate in einer unerwarteten Art und Weise (oder auch nicht).

Andere Tipps

Sie sagen, zwei Trigger in einer partitionierten Tabelle zu verwenden oder die @SQLInsert Anmerkung hier: https: // gist.github.com/copiousfreetime/59067

Wird angezeigt, wenn Sie Regeln statt Auslöser für den Einsatz verwenden können, dann kann es die richtige Nummer zurück, aber nur mit einer einzigen Regel ohne eine WHERE-Anweisung.

ref1

ref2

ref3

eine weitere Option kann eine Ansicht erstellen, dass ‚Wraps‘ die partitionierten Tabelle, Sie dann die neue Zeile zurückkehren, um eine erfolgreiche Reihe Update, um anzuzeigen, ohne versehentlich eine zusätzliche unerwünschte Zeile der Haupttabelle hinzufügen.

create view tablename_view as select * from tablename; -- create trivial wrapping view

CREATE OR REPLACE FUNCTION partitioned_insert_trigger() -- partitioned insert trigger
RETURNS TRIGGER AS $$
BEGIN
   IF (NEW.partition_key>= 5500000000 AND
       NEW.partition_key <  6000000000) THEN
      INSERT INTO tablename_55_59 VALUES (NEW.*);
   ELSIF (NEW.partition_key >= 5000000000 AND
          NEW.partition_key <  5500000000) THEN
      INSERT INTO tablename_50_54 VALUES (NEW.*);
   ELSIF (NEW.partition_key >= 500000000 AND
          NEW.partition_key  <  1000000000) THEN
      INSERT INTO tablename_5_9 VALUES (NEW.*);
   ELSIF (NEW.partition_key >= 0 AND
          NEW.partition_key <  500000000) THEN
      INSERT INTO tablename_0_4 VALUES (NEW.*);
   ELSE
      RAISE EXCEPTION 'partition key is out of range.  Fix the trigger function';
   END IF;
   RETURN NEW; -- RETURN NEW in this case, typically you'd return NULL from this trigger, but for views we return NEW
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER insert_view_trigger
   INSTEAD OF INSERT ON tablename_view
   FOR EACH ROW EXECUTE PROCEDURE partitioned_insert_trigger(); -- create "INSTEAD OF" trigger

ref: http://www.postgresql.org/docs/ 9.2 / static / Trigger-definition.html

Wenn Sie die Ansicht Wrapper Route ging eine Option ist auch trivial zu definieren „anstelle von“ Trigger für Lösch- und Update, als auch, dann können Sie den Namen der View-Tabelle verwenden Sie einfach anstelle der normalen Tabelle in allen Geschäften .

Eine weitere Option, die die Ansicht verwendet, ist ein Insert Regel zu erstellen, so dass alle Einsätze auf der Haupttabelle der Ansicht gehen [die ihre Trigger verwendet], ex (vorausgesetzt, Sie haben bereits partitioned_insert_trigger und tablename_view und insert_view_trigger erstellt, wie oben aufgeführt)

create RULE use_right_inserter_tablename AS
      ON INSERT TO tablename
      DO INSTEAD insert into tablename_view VALUES (NEW.*);

Dann wird es Ihren neuen Arbeitsansicht Wrapper Einsatz verwendet werden.

thnx! es hat den Trick, keine Probleme poped oben, so weit:) .... eine Sache, du ... ich musste BatcherFactory Klasse implementieren und setzen sie die persistence.xml Datei int, wie folgt aus:

property name="hibernate.jdbc.factory_class" value="path.to.my.batcher.factory.implementation"

von dieser Fabrik i meine batcher Implementierung mit dem Code aufgerufen haben über

ps Hibernate Core 3.2.6 GA

Dank noch einmal

stand ich vor dem gleichen Problem, während Dokumente durch Hibernate Einfügen nach viel Suche festgestellt, dass es erwartet, dass aktualisierte Zeilen sollten so statt null Änderung der Triggerprozedur zu neuen erstattet, der das Problem beheben wird, wie unten

RETURN NEU

fand ich eine andere Lösung für das gleiche Problem auf dieser Webseite :

Dies legt nahe, die gleiche Lösung, die die @rogerdpack, die Zurück Null Ändern Zurück NEW , und das Hinzufügen eines neuen Trigger, der die duplizierten Tupel im Master löscht mit der Abfrage:

DELETE FROM ONLY master_table;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top