Search code examples
oracle-databaseplsqltriggersoracle12c

What's wrong with that AFTER DELETE TRIGGER?


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.


Solution

  • 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.