Careeroza
Cascade Types
What Cascading Means
Without cascading, every entity must be saved on its own: save the order, then save each item. Cascading tells Hibernate: "when I do operation X on the parent, do X on these children too".
| CascadeType | Parent operation passed to children |
|---|---|
PERSIST | persist() / save() of a new parent saves new children |
MERGE | merge() of a detached parent merges the children |
REMOVE | deleting the parent deletes the children |
REFRESH | reloading the parent from the DB reloads the children |
DETACH | detaching the parent detaches the children |
ALL | all of the above |
Cascade from Order to Items
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderItem> items = new ArrayList<>();Order order = new Order(user);
order.addItem(new OrderItem(phoneCase, 1, new BigDecimal("299")));
order.addItem(new OrderItem(charger, 2, new BigDecimal("749")));
orderRepository.save(order); // one call saves the order AND both itemsGenerated SQL
orderRepository.save(order);Example output
DEBUG org.hibernate.SQL : insert into orders (status,total,user_id) values (?,?,?) DEBUG org.hibernate.SQL : insert into order_items (order_id,price,product_id,quantity) values (?,?,?,?) DEBUG org.hibernate.SQL : insert into order_items (order_id,price,product_id,quantity) values (?,?,?,?)
Where Cascading Belongs
Cascade from a parent to children it owns (whose life depends on the parent). Never cascade towards shared, independent entities.
| Association | Cascade? | Why |
|---|---|---|
Order.items | ALL + orphanRemoval | an item cannot exist without its order |
OrderItem.product | none | deleting an order must not delete the product |
Product.category | none | many products share one category |
User.wishlist (ManyToMany) | never REMOVE | it would delete products other users wishlisted |
Note: CascadeType.REMOVE on a @ManyToOne or @ManyToMany is almost always a bug. Deleting one order item could delete the product, and with it every other order's reference fails.
Practice
Exercise: A Product has a list of ProductImage rows (URLs of photos). Images are uploaded with the product and deleted with it. Write the mapping on Product.
Show answer
@OneToMany(mappedBy = "product", cascade = CascadeType.ALL, orphanRemoval = true)
@OrderColumn(name = "position") // optional: keep the photo order
private List<ProductImage> images = new ArrayList<>();
public void addImage(ProductImage img) { images.add(img); img.setProduct(this); }
public void removeImage(ProductImage img) { images.remove(img); img.setProduct(null); }