【发布时间】:2011-12-29 09:29:35
【问题描述】:
我有一个使用 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)
);
【问题讨论】:
-
触发触发器的查询是什么?历史表是否在 {original_key, date} 上有唯一的二级索引?顺便说一句:“日期”对于列来说是一个坏名称,因为它是一个典型名称。顺便说一句:也许您应该将表定义(包括约束)添加到您的问题中。
-
@wildplasser 确实不是以这种方式调用该字段的真实表。我在这里更改了它,以便您可以更好地理解它,因为名称不是英文的。如果我直接在表上进行更新/删除,则触发器可以完美运行。问题是当我对保存在 my_table 中的实体调用 EntityManager 上的 delete() 方法时。
-
请显示(相关部分)您的表定义。
-
@wildplasser 表定义在末尾添加
-
谢谢。 historial_table {id_mytable,date_now} 上没有二级索引?
标签: hibernate postgresql triggers plpgsql rowcount