hibernate insert batch with partitioned postgresql

前端 未结 6 1549
一生所求
一生所求 2021-02-07 21:27

is there a solution for batch insert via hibernate in partitioned postgresql table? currently i\'m getting an error like this...

ERROR org.hibernate.jdbc.Abstra         


        
6条回答
  •  死守一世寂寞
    2021-02-07 21:46

    Appears if you can use RULES instead of triggers for the insert, then it can return the right number, but only with a single RULE without a WHERE statement.

    ref1

    ref2

    ref3

    another option may be to create a view that 'wraps' the partitioned table, then you return the NEW row out to indicate a successful row update, without accidentally adding an extra unwanted row to the master table.

    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

    If you went the view wrapper route one option is to also define trivial "instead of" triggers for delete and update, as well, then you can just use the name of the view table in place of your normal table in all transactions.

    Another option that uses the view is to create an insert rule so that any inserts on the main table go to the view [which uses its trigger], ex (assuming you already have partitioned_insert_trigger and tablename_view and insert_view_trigger created as listed above)

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

    Then it will use your new working view wrapper insert.

提交回复
热议问题