Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cascading Deletes/Updates using JPA or Inside of Database?

Performance is key: Is it better to cascade deletes/updates inside of the Database or let Hibernate/JPA take care of it?

Will this effect the ability to query for the data if cascades are inside of the DBMS?

I am using HSQLDB if that matters.

like image 596
mainstringargs Avatar asked Nov 06 '22 22:11

mainstringargs


1 Answers

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

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');

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.

like image 157
Bill Karwin Avatar answered Nov 11 '22 04:11

Bill Karwin