2008-09-17 11 views
10

bölümlenmiş postgresql tablodaki hazırda bekletme yoluyla toplu iş için bir çözüm var mı? Şu anda ben bu sorun çözüldü ben bu bağlantıyı http://lists.jboss.org/pipermail/hibernate-dev/2007-October/002771.html bulduk ama her yerde internet üzerinde bulamıyorum böyle bir hata ...Bölünmüş postgresql ile hibernate insert toplu

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).... 

edilir alıyorum yoksa etrafında

+0

Hazırda bekletme 3.5 için başka çözümler var mı? –

cevap

4

almak nasıl Hibernate.jdbc.factory_class özelliğini ayarlayarak özel bir Batcher kullanmayı deneyebilirsiniz. Hazırda bekletme, toplu işlemlerin güncelleştirme sayısını kontrol etmeyeceğinden emin olmak sorununuzu çözebilir, özel Batcher sınıfını BatchingBatcher sınıfını genişleterek ve ardından doExecuteBatch (...) yöntemini geçersiz kılmak için aşağıdaki gibi görünmesini sağlayabilirsiniz:

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

     } 

    } 

Yeni yöntemin, hazırlanmış ifadeleri yürütme sonuçlarını kontrol etmediğini unutmayın. Bu değişikliğin beklenmedik bir şekilde (veya belki de değil) hazırda bekletilmesini etkileyebileceğini unutmayın.

2

thnx!

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

: ben böyle , BatcherFactory sınıf uygulamak ve onu persistence.xml dosyayı int koymak zorunda) .... sen bir şey ... : Bu hile, bugüne kadar poped sorun yok, yaptığımız o fabrikadan i 3.2.6 ga

ps hazırda çekirdek yukarıdaki kod ile benim besleyici uygulama

teşekkür Onlar söyleyecek bir kez daha

+0

Parti sayımı yok sayılırsa, sorununuzu giderir mi, yoksa hatayı görmezden mi geliyor? Aynı hatayı yaşıyorum ve neden bunun olduğunu ya da Batcher'ı atlamak için geçersiz kılmaya çalışırsam bunun ne anlama geldiğini anlatamıyorum. – Dougnukem

+1

Bu, Hazırda Bekletme 3.2.6 GA ile nasıl çalışır BatchingBatcher uygulaması, özel bir alan olarak batchSize özelliğine sahiptir, bu yüzden ona erişimim yoktur. – Dougnukem

+1

sorunu göz ardı eder, ancak tüm değerler DB içinde, bu yüzden benim için hile yapar ... Ben çalışılan AbstractBatcher sınıfı – tropikalista

1

Görünüyor: Burada

usta ekstra satırı silmek tetik sonra birlikte bir örnektir WHERE ifadesi olmayan tek bir RULE.

ref2

ref3

başka bir seçenek 'uygulamalar' bölümlenmiş tablo, o zaman başarılı bir satır güncelleştirme belirtmek için YENİ satır dışarı dönmek bir görünüm oluşturmak olabilir

ref1

olmadan yanlışlıkla ana masaya fazladan istenmeyen satır ekleyerek.

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

tek seçenek aynı zamanda, silme ve güncelleme için tetikler "yerine" önemsiz tanımlamaktır görünümü sarıcı rotayı giderse, o zaman sadece ismini kullanabilirsiniz tüm işlemlerde tabloyu normal tablonuzun yerine görüntüleyin.

Görünümü kullanan başka bir seçenek, ana tablodaki tüm eklerin [tetikleyicisini kullanan] görünüme geçmesini sağlamak için bir ekleme kuralı oluşturmaktır; ex (yukarıdaki partitioned_insert_trigger ve tablename_view ve insert_view_trigger öğelerinin yukarıda listelendiği gibi oluşturulduğunu varsayarak)

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

Daha sonra yeni çalışma görünümü sarmalayıcı ekinizi kullanacaktır. hazırda yoluyla doküman eklerken aramanın çok o

aşağıda gösterildiği gibi güncellenen satırlar bunun yerine sorunu çözmek hangi tetik prosedüründe yeniye boş değişimin onu bir iade edilmesi gerektiğini bekliyor bulundu sonra
0

aynı sorunla karşı karşıya

RETURN NEW