पाठ 12 / 25
Cascades, Orphan Removal and Entity Equality
Use cascade types and orphanRemoval correctly and implement equals and hashCode for entities.
Propagating operations safely
Cascading propagates operations from a parent to related entities: with cascade = CascadeType.PERSIST, persisting an order also persists its new lines; MERGE, REMOVE, REFRESH, DETACH and ALL work similarly. Cascade along composition relationships, where children belong to the parent (order → order lines), and not along associations between independent aggregates (order → customer): cascading REMOVE from an order to its customer would delete the customer. orphanRemoval = true deletes a child when it is removed from the parent's collection, again appropriate only for owned children. Entities need careful equals/hashCode: identity-based equality works within one persistence context, but entities in HashSets across states need stable hashing. Common safe approaches: base equality on a natural or business key that never changes, or on the ID with a constant hashCode (so the hash does not change when a new entity receives its ID at persist). Never base equality on all fields, and avoid Lombok @Data on entities, which generates field-based equals and toString methods that can trigger lazy loading or infinite recursion.
Cascade within an aggregate and safe equality
Lines cascade from their order; the customer does not.
@Entity
public class PurchaseOrder {
@Id @GeneratedValue private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false) // independent aggregate: NO cascade
private Customer customer;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderLine> lines = new ArrayList<>(); // owned children: cascade + orphans
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PurchaseOrder other)) return false;
return id != null && id.equals(other.id); // transient entities are only equal to themselves
}
@Override
public int hashCode() {
return PurchaseOrder.class.hashCode(); // constant: stable across persist
}
}Cascade REMOVE on many-to-many is dangerous
Cascading REMOVE from an article to its tags deletes the tags for every other article too. Cascade only into entities that cannot exist without the parent.
त्वरित जाँच: Where is CascadeType.ALL with orphanRemoval appropriate?
- From an order to its order lines, which belong only to that order
- From an order to its customer
- From any entity to every related entity
- On every @ManyToMany
Answer
From an order to its order lines, which belong only to that order — Cascade and orphan removal suit owned children in a composition, not independent entities.