Real World Example

Editing a Swiggy Cart Before Checkout

Food apps like Swiggy and Zomato let you change quantities, remove dishes and add new ones before paying. With a Cart aggregate that owns its lines, a single "update cart" call can sync the whole collection, and cascading plus orphan removal produce exactly the right INSERT, UPDATE and DELETE statements.

@Entity
@Table(name = "carts")
public class Cart {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", unique = true)
    private User user;

    @OneToMany(mappedBy = "cart", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<CartItem> items = new ArrayList<>();

    public void sync(Map<Long, Integer> wanted, Function<Long, Product> productRef) {
        // 1. remove lines that are no longer wanted -> orphan DELETE
        items.removeIf(ci -> !wanted.containsKey(ci.getProduct().getId()));
        // 2. update quantities of existing lines -> UPDATE (dirty checking)
        for (CartItem ci : items) ci.setQuantity(wanted.get(ci.getProduct().getId()));
        // 3. add new lines -> cascaded INSERT
        Set<Long> present = items.stream().map(ci -> ci.getProduct().getId()).collect(Collectors.toSet());
        wanted.forEach((productId, qty) -> {
            if (!present.contains(productId)) {
                CartItem ci = new CartItem(productRef.apply(productId), qty);
                ci.setCart(this);
                items.add(ci);
            }
        });
    }
}

The Service and the SQL

@Transactional
public CartDto updateCart(Long userId, Map<Long, Integer> wanted) {
    Cart cart = cartRepository.findByUserId(userId).orElseThrow();
    cart.sync(wanted, productRepository::getReferenceById);
    return CartDto.from(cart);
}

Example

Cart had biryani x1 and raita x2; the user changes biryani to x2, removes raita and adds gulab jamun:

curl -X PUT localhost:8080/api/cart -H "Content-Type: application/json" -d '{"11":2,"27":1}'

Example output

DEBUG org.hibernate.SQL : select c1_0.id,c1_0.user_id from carts c1_0 where c1_0.user_id=?
DEBUG org.hibernate.SQL : select i1_0.cart_id,i1_0.id,i1_0.product_id,i1_0.quantity from cart_items i1_0 where i1_0.cart_id=?
DEBUG org.hibernate.SQL : insert into cart_items (cart_id,product_id,quantity) values (?,?,?)
DEBUG org.hibernate.SQL : update cart_items set cart_id=?,product_id=?,quantity=? where id=?
DEBUG org.hibernate.SQL : delete from cart_items where id=?

HTTP/1.1 200 OK
{"items":[{"productId":11,"name":"Chicken Biryani","quantity":2},{"productId":27,"name":"Gulab Jamun","quantity":1}]}

Tip: Hibernate orders the statements at flush: inserts first, then updates, then collection removals and deletes. You write plain Java; the SQL order is handled for you.