Scenario: remove one item from order.items (a plain List.remove, via the addItem/removeItem helpers that keep both sides in sync) and save() the order. 1. select o1_0.id,c1_0.id,c1_0.name,i1_0.order_id,i1_0.id,i1_0.quantity,i1_0.sku,o1_0.version from jpa_order o1_0 left join jpa_customer c1_0 on c1_0.id=o1_0.customer_id left join jpa_order_item i1_0 on o1_0.id=i1_0.order_id where o1_0.id=? 2. delete from jpa_order_item where id=? total statements: 2 orphanRemoval = true on the @OneToMany turns "no longer in the collection" into a DELETE for that row. Without orphanRemoval, the row survives with a dangling (nulled or stale) order_id, which is the more common real-world bug report.