Неожиданное количество строк при использовании триггера PostgreSQL и спящего режима - PullRequest
3 голосов
/ 15 ноября 2011

У меня есть приложение, которое использует Hibernate, и мне нужно включить триггер для копирования в таблицу истории всех строк, измененных или удаленных в таблице.После включения триггера PostgreSQL приложение не работает должным образом и выдает следующую ошибку:

org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException: пакетное обновление вернуло неожиданное количество строк из обновления [0];фактическое количество строк: 0;ожидается: 1;вложенным исключением является org.hibernate.StaleStateException: Пакетное обновление вернуло неожиданное количество строк из обновления [0];фактическое количество строк: 0;Ожидается: 1

После некоторого гугления я обнаружил, что эта ошибка возникает из-за того, что Hibernate выполняет проверку затронутых строк обновлением sql, а возвращенные строки не ожидаютсяиз-за того, что триггер также сделал обновление.Я видел, что это можно исправить, отключив счетчик строк на триггере.Но у PostgreSQL, похоже, нет альтернативы для 'set nocount on'.

Как решить проблему в триггере PostgreSQL, как показано ниже?

Спасибо

CREATE OR REPLACE FUNCTION my_trigger_fnc() RETURNS TRIGGER AS $my_trigger_fnc$
    DECLARE
        nowDate timestamp := now();
    BEGIN

        INSERT INTO historial_table (
                id,
                date_now,
                id_mytable,
                --some other fields
                ...
                ) 
        VALUES (              
                nextVal('historial_table_seq'),
                nowDate,
                OLD.id_mytable
                --some other fields
                ...
               );
        RETURN NEW;
    END;
$my_trigger_fnc$ LANGUAGE plpgsql;

CREATE TRIGGER my_trigger BEFORE UPDATE OR DELETE 
    ON my_table FOR EACH ROW 
    EXECUTE PROCEDURE my_trigger_fnc();

ОБНОВЛЕНИЕ: таблицы похожи на эту:

CREATE TABLE historial_table(
    id integer,
    date_now timestamp NOT NULL,
    id_mytable integer NOT NULL,
    nserie character varying(255),
    idstore integer,
    idmodel integer,
    automatic boolean,
    broken boolean,
    idAlb integer,
    idInc integer,
    id_item integer,
    date_assign timestamp,
    PRIMARY KEY (id)  
);

CREATE TABLE my_table(
    id_mytable integer NOT NULL,
    nserie character varying(255),
    idstore integer,
    idmodel integer,
    automatic boolean,
    broken boolean,
    idAlb integer,
    idInc integer,
    id_item integer,
    date_assign timestamp,
    PRIMARY KEY (id_mytable)  
);

1 Ответ

5 голосов
/ 15 ноября 2011

«Возврат NEW»;подозрительно на УДАЛИТЬ.Может привести в замешательство количество строк (NULL == ноль?) http://developer.postgresql.org/pgdocs/postgres/plpgsql-trigger.html (очень общее; не предназначено для того, чтобы вас оскорблять ...) Возможно, вам нужен переключатель TG_OP.

...