How does JPA orphanRemoval=true differ from the ON DELETE CASCADE DML clause
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 disconnectedAddress
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.
The moment you remove a child entity from the collection you will also be removing that child entity from the DB as well. orphanRemoval also implies that you cannot change parents; if there's a department that has employees, once you remove that employee to put it in another deparment, you will have inadvertantly removed that employee from the DB at flush/commit(whichver comes first). The morale is to set orphanRemoval to true so long as you are certain that children of that parent will not migrate to a different parent throughout their existence. Turning on orphanRemoval also automatically adds REMOVE to cascade list.
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.