I'm trying to use a trigger to clean some @OneToOne
related entities upon deletion of another (via SQL). Let's suppose I have a Person
and an OrgUnit
both referencing some Address
. That Address
is mapped with an ADDRESS_ID
and related foreign key constraints.
The following trigger compiles just fine:
CREATE OR REPLACE TRIGGER ON_DELETE_PERSON
AFTER DELETE ON PERSON
FOR EACH ROW
BEGIN
DELETE FROM ADDRESS WHERE ID = :OLD.ADDRESS_ID;
END;
/
But whenever I try to delete a Person
the following error is thrown:
DELETE FROM PERSON WHERE ID = 21179
ORA-04091: table MY_SCHEMA.PERSON is mutating, trigger/function may not see it
ORA-06512: in "MY_SCHEMA.ON_DELETE_PERSON", row 2
ORA-04088: error during execution of trigger 'MY_SCHEMA.ON_DELETE_PERSON'
What must be changed to make this trigger work?
Within the Java code I could simply handle this with CascadeStyle.DELETE
... but I want to transfer that responsibility to the database to allow proper ON DELETE CASCADE
behavior for all the data.
-- CASCADE DELETE on ORGUNIT deletion...
ALTER TABLE PERSON ADD CONSTRAINT PERSON_F01
FOREIGN KEY (ORGUNIT_ID) REFERENCES ORGUNIT (ID)
ON DELETE CASCADE ENABLE VALIDATE;
-- SET NULL on ADDRESS deletion...
ALTER TABLE PERSON ADD CONSTRAINT PERSON_F02
FOREIGN KEY (ADDRESS_ID) REFERENCES ADDRESS (ID)
ON DELETE SET NULL ENABLE VALIDATE;
So, deleting an ORGUNIT
automatically deletes all related PERSON
too... but the ADDRESS
would remain in the database. The TRIGGER above is meant to handle this case.
So after a few comments the answer pops up:
The FK constraint with ON DELETE SET NULL
fires back to the table and causes that exception. Looks like I can't have both...
I'll get rid of the ON DELETE
definition and risk the FK constraint error in that case. The cascaded delete via the trigger has the higher value to me.