How does JPA orphanRemoval=true differ from the ON DELETE CASCADE DML clause

I am a little confused about the JPA 2.0 orphanRemoval attribute.

I think I can see it is needed when I use my JPA provider's DB generation tools to create the underlying database DDL to have an ON DELETE CASCADE on the particular relation.

However, if the DB exists and it already has an ON DELETE CASCADE on the relation, is this not enough to cascade the deletion appropriately? What does the orphanRemoval do in addition?

Cheers


orphanRemoval has nothing to do with ON DELETE CASCADE.

orphanRemoval is an entirely ORM-specific thing. It marks "child" entity to be removed when it's no longer referenced from the "parent" entity, e.g. when you remove the child entity from the corresponding collection of the parent entity.

ON DELETE CASCADE is a database-specific thing, it deletes the "child" row in the database when the "parent" row is deleted.


An example taken form here:

When an Employee entity object is removed, the remove operation is cascaded to the referenced Address entity object. In this regard, orphanRemoval=true and cascade=CascadeType.REMOVE are identical, and if orphanRemoval=true is specified, CascadeType.REMOVE is redundant.

The difference between the two settings is in the response to disconnecting a relationship. For example, such as when setting the address field to null or to another Address object.

  • If orphanRemoval=true is specified the disconnected Address instance is automatically removed. This is useful for cleaning up dependent objects (e.g. Address) that should not exist without a reference from an owner object (e.g. Employee).

  • If only cascade=CascadeType.REMOVE is specified, no automatic action is taken since disconnecting a relationship is not a remove operation.

To avoid dangling references as a result of orphan removal, this feature should only be enabled for fields that hold private non shared dependent objects.

I hope this makes it more clear.