22.214.171.124.2. Related Entities Processing Policy
The platform offers a mechanism for managing related entities when deleting, which is largely similar to ON DELETE rules for database foreign keys. This mechanism works on the middle tier and uses @OnDelete, @OnDeleteInverse annotations on entity attributes.
@OnDelete annotation is processed when the entity in which this annotation is found is deleted, but not the one pointed to by this annotation (this is the main difference from cascade deletion at the database level).
@OnDeleteInverse annotation is processed when the entity which it points to is deleted (which is similar to cascade deletion at foreign key level in the database). This annotation is useful when the object being deleted has no attribute that can be checked before deletion. Typically, the object being checked has a reference to the object being deleted, and this is the attribute that should be annotated with
Annotation value can be:
DeletePolicy.DENY– prohibits entity deletion, if the annotated attribute is not
nullor not an empty collection.
DeletePolicy.CASCADE– cascade deletion of the annotated attribute.
DeletePolicy.UNLINK– disconnect the link with the annotated attribute. It is reasonable to disconnect the link only in the owner side of the association – the one with
@JoinColumnannotation in the entity class.
Prohibit deletion of entity with references:
DeletePolicyExceptionwill be thrown if you try to delete
Customerinstance, which is referred to by at least one
@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "CUSTOMER_ID") @OnDeleteInverse(DeletePolicy.DENY) protected Customer customer;
@OneToMany(mappedBy = "customer") protected List<Order> orders;
Cascade deletion of related collection elements: deletion of
Roleinstance causes all
Permissioninstances to be deleted as well.
@OneToMany(mappedBy = "role") @OnDelete(DeletePolicy.CASCADE) protected Set<Permission> permissions;
@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "ROLE_ID") protected Role role;
Disconnect the links with related collection elements: deletion of
Roleinstance leads to setting to null references to this
Permissioninstances included in the collection.
@OneToMany(mappedBy = "role") protected Set<Permission> permissions;
@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "ROLE_ID") @OnDeleteInverse(DeletePolicy.UNLINK) protected Role role;
Be careful when using
UNLINKpolicies. During this process, all instances of the related objects are fetched from the database, modified and then saved.
For example, if
@OnDeleteInverse(CASCADE)policy is set on
Job.customerattribute in a
Jobassociation with many jobs to one customer, if you set
Job.customerattribute, all jobs will be retrieved and modified when deleting a Customer instance. This may overload the application server or the database.
On the other hand, using
@OnDeleteInverse(DENY)is safe, as it only involves counting the number of the related objects. If there are more than
0, an exception is thrown. This makes use of
Related entities processing is implemented at Middleware using Entity Listeners.