Vra

Daar is 'n oplossing vir 'n batch insetsel via hiberneer in Gepartitioneerd postgresql tafel? tans Ek kry 'n fout soos hierdie ...

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)....
// lyste:

Ek het hierdie skakel http gevind. jboss.org/pipermail/hibernate-dev/2007-October/002771.html maar ek kan nie op enige plek op die web te vind is hierdie probleem opgelos of hoe dit kan wees kry om

Was dit nuttig?

Oplossing

Jy mag dalk wil om te probeer om met behulp van 'n persoonlike Batcher deur die oprigting van die eiendom hibernate.jdbc.factory_class. Om seker te maak hiberneer sal nie check die update telling van joernaal bedrywighede kan jou probleem op te los, kan jy bereik wat deur die maak van jou persoonlike Batcher brei die klas BatchingBatcher, en dan dwing om die metode doExecuteBatch (...) om te lyk soos:

    @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;
            }

        }

    }

Let daarop dat die nuwe metode nie die resultate van die uitvoering van die voorbereide state controleert. Hou in gedagte dat die maak van hierdie verandering hiberneer kan beïnvloed in 'n onverwagte manier (of dalk nie).

Ander wenke

Hulle sê om twee snellers gebruik in 'n afgeskorte tafel of die @SQLInsert body hier: http://www.redhat.com/f/pdf/jbw/jmlodgenski_940_scaling_hibernate.pdf bladsye 21-26 (dit maak ook melding van 'n @SQLInsert spesifiseer 'n String metode).

Hier is 'n voorbeeld met 'n na sneller om die ekstra ry in die meester verwyder: https: // gist.github.com/copiousfreetime/59067

Verskyn as jy REËLS in plaas van snellers kan gebruik vir die insetsel, dan kan dit die regte hoeveelheid terugkeer, maar net met 'n enkele regeer sonder 'n WAAR verklaring.

ref1

ref2

ref3

'n ander opsie kan wees om 'n standpunt dat 'vou' die verdeel tafel, dan is die nuwe ry terug jou uit om 'n suksesvolle ry update dui, sonder ongeluk 'n ekstra ongewenste ry toe te voeg tot die meester tafel te skep.

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 / statiese / sneller-definition.html

As jy die oog wrapper roete een opsie is om ook te definieer triviale "in plaas van" snellers vir delete en werk, asook gegaan, dan kan jy net gebruik maak van die naam van die oog tafel in plaas van jou gewone tafel in alle transaksies .

Nog 'n opsie wat die oog gebruik is om 'n insetsel reël te skep sodat enige insetsels op die hooftafel na die vertoning [wat sy sneller gebruik], ex (as jy reeds 'partitioned_insert_trigger en tablename_view en insert_view_trigger geskep soos hierbo gelys)

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

Toe dit sal jou nuwe werk siening wrapper insetsel te gebruik.

thnx! dit het die truuk, geen probleme poped up, so ver:) .... een ding kom jy ... Ek moes implementeer BatcherFactory klas en sit dit die persistence.xml lêer int, soos volg:

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

van daardie fabriek i my batcher implementering met die kode het genoem hierbo

ps hiberneer kern 3.2.6 GA

dankie weereens

Ek gekonfronteer met dieselfde probleem, terwyl die invoeging van dokumente deur hiberneer na baie soek het bevind dat dit verwag dat opgedateer rye so in plaas van nul verander dit na nuwe in sneller prosedure wat die probleem sal oplos moet teruggestuur word soos hieronder

Terug NEW

Ek het gevind dat 'n ander oplossing vir dieselfde probleem op hierdie webblad :

Dit dui dieselfde oplossing wat @rogerdpack gesê, die verandering van die Terug Null Terug NEW , en die toevoeging van 'n nuwe sneller wat die gedupliseer tuple verwyder in die meester met die navraag:

DELETE FROM ONLY master_table;
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top