且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用JPA或在数据库内部级联删除/更新?

更新时间:2023-02-01 13:09:17

在级联更新的情况下,如果数据库中有外键约束,则根本无法在应用程序空间中做到这一点.

In the case of cascading updates, you simply cannot do it in application space if you have foreign key constraints in the database.

示例:假设您有一个针对美国各州的查找表,主键为两个字母的缩写.然后,您有了一个表,用于引用该表的邮寄地址.有人告诉您,您错误地给Montana缩写了"MO"而不是"MT",因此您需要在查找表中对其进行更改.

Example: say you have a lookup table for US states, with a primary key of the two-letter abbreviation. Then you have a table for mailing addresses that references it. Someone tells you that you mistakenly gave Montana the abbreviation "MO" instead of "MT" so you need to change it in the lookup table.

CREATE TABLE States (st CHAR(2) PRIMARY KEY, state VARCHAR(20) NOT NULL);
INSERT INTO States VALUES ('MO', 'Montana');

CREATE TABLE Addresses (addr VARCHAR(20), city VARCHAR(20), st CHAR(2), zip CHAR(6),
  FOREIGN KEY (st) REFERENCES States(st));
INSERT INTO Addresses VALUES ('1301 East Sixth Ave.', 'Helena', 'MO', '59620');

现在,您无需数据库侧级联更新,即可解决错误.下面是使用MySQL 5.0进行的测试(假设密苏里州没有记录,实际上它的缩写是"MO").

Now you go to fix the mistake, without the aid of database-side cascading updates. Below is a test using MySQL 5.0 (assume no records exist for Missouri, which actually does use the abbreviation "MO").

UPDATE States SET st = 'MT' WHERE st = 'MO';

ERROR 1451 (23000): Cannot delete or update a parent row: 
 a foreign key constraint fails (`test/addresses`, 
 CONSTRAINT `addresses_ibfk_1` FOREIGN KEY (`st`) REFERENCES `states` (`st`))

UPDATE Addresses SET st = 'MT' WHERE st = 'MO';

ERROR 1452 (23000): Cannot add or update a child row: 
 a foreign key constraint fails (`test/addresses`, 
 CONSTRAINT `addresses_ibfk_1` FOREIGN KEY (`st`) REFERENCES `states` (`st`))

UPDATE Addresses JOIN States USING (st)
SET Addresses.st = 'MT', States.st = 'MT'
WHERE States.st = 'MO';

ERROR 1451 (23000): Cannot delete or update a parent row: 
 a foreign key constraint fails (`test/addresses`, 
 CONSTRAINT `addresses_ibfk_1` FOREIGN KEY (`st`) REFERENCES `states` (`st`))

没有应用程序侧查询可以解决此问题.在强制执行参照完整性约束之前,您需要在数据库中进行级联更新,以便原子地在两个表中执行更新.

No application-side query can solve this situation. You need cascading updates in the database in order to perform the update in both tables atomically, before the referential integrity constraint is enforced.