BackendBench
Coffee

Unravel › Java concepts › Persistence and JPA

Persistence

JPA relationships, cascade and orphan removal

Relationship mappings tell JPA how tables are linked.

Learn these first

At a glance

Mental model

A folder of documents.

What happens, in order
  1. 1In a one-to-many, the foreign key lives in the child tableThe @ManyToOne side with @JoinColumn(name = "order_id") is the owner; the @OneToMany(mappedBy = "order") side is only a read-friendly mirror.
  2. 2cascade = CascadeType.ALL passes persist, merge, remove and refresh from parent to childrenorphanRemoval = true deletes a child that is removed from the parent collection.
  3. 3Many-to-many needs a join table (@JoinTable)If the link has data of its own (quantity, date), model it as a separate entity with two @ManyToOne instead.
  4. 4@ElementCollection stores a collection of simple values or embeddables in its own table without a separate entity
Remember
Watch out
Updating only the mappedBy side and seeing nothing savedCascadeType.ALL on associations to shared dataUsing a bag (List) for large many-to-many collectionsMissing helper methods so both sides drift apart
Example (highlighted lines explain it)
@Entitypublic class Invoice {    @Id @GeneratedValue    private Long id;    @OneToMany(mappedBy = "invoice", cascade = CascadeType.ALL, orphanRemoval = true)    private List<InvoiceLine> lines = new ArrayList<>();    public void addLine(InvoiceLine line) {        lines.add(line);        line.setInvoice(this);    }}
  1. line 6 uses CascadeType, the core of JPA relationships, cascade and orphan removal
Read the full explanation (about 2 min)

Relationship mappings tell JPA how tables are linked. Two details decide whether the model behaves: who owns the foreign key, and what happens to child rows when the parent is saved or deleted (cascade).

A mental model

A folder of documents. Cascade means "when I throw away the folder, throw away its contents too". The owning side is whoever holds the label that says which folder a document belongs to.

How it works

In a one-to-many, the foreign key lives in the child table. The @ManyToOne side with @JoinColumn(name = "order_id") is the owner; the @OneToMany(mappedBy = "order") side is only a read-friendly mirror.

cascade = CascadeType.ALL passes persist, merge, remove and refresh from parent to children. orphanRemoval = true deletes a child that is removed from the parent collection.

Many-to-many needs a join table (@JoinTable). If the link has data of its own (quantity, date), model it as a separate entity with two @ManyToOne instead.

@ElementCollection stores a collection of simple values or embeddables in its own table without a separate entity.

Going deeper

Always keep both sides in sync with helper methods (order.addLine(line) sets line.setOrder(order)). Changing only the mirror side does nothing in the database because it is not the owner.

Do not cascade REMOVE across independent aggregates (a customer deleting all their orders deleting the products). Cascade belongs inside one aggregate, where children cannot live without the parent.

A List without an order column treated as a bag makes Hibernate delete and re-insert all rows on a change. A Set, or an @OrderColumn, avoids that. Also @ManyToMany with CascadeType.REMOVE can wipe shared rows.

Under the hood

On flush Hibernate compares each managed entity with its loaded snapshot and walks the cascade graph, scheduling inserts, updates and deletes in a fixed order (inserts first, deletes last). Collection wrappers (PersistentBag, PersistentSet) track changes so that only the differences are written.

Common mistakes

  • Updating only the mappedBy side and seeing nothing saved.
  • CascadeType.ALL on associations to shared data.
  • Using a bag (List) for large many-to-many collections.
  • Missing helper methods so both sides drift apart.

How Unravel recognises it

When you paste code, Unravel looks for these signs of jpa relationships, cascade and orphan removal. Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Frequently asked questions

What is JPA relationships, cascade and orphan removal?

Relationship mappings tell JPA how tables are linked. Two details decide whether the model behaves: who owns the foreign key, and what happens to child rows when the parent is saved or deleted (cascade).

What are the most common mistakes with JPA relationships, cascade and orphan removal?

Updating only the mappedBy side and seeing nothing saved. CascadeType.ALL on associations to shared data. Using a bag (List) for large many-to-many collections. Missing helper methods so both sides drift apart.

How can I see JPA relationships, cascade and orphan removal in real code?

Paste your own Java into Unravel and it will point out where jpa relationships, cascade and orphan removal appears, explain how it works at the detail level you choose, and draw the flow of the code around it.