The Four States

States and Transitions

new Product(...)
         |
         v
   +-----------+   persist()    +-----------+   remove()    +-----------+
   | TRANSIENT | -------------> |  MANAGED  | ------------> |  REMOVED  |
   +-----------+                +-----------+ <------------ +-----------+
                                 ^    |   ^      persist()        |
                    find()/query |    |   | merge()               | commit -> DELETE
                                 |    |   |                       v
                    (database) --+    |   +------+            (row gone)
                                      |          |
                     detach()/clear() |    +-----------+
                     close()/commit*  +--> | DETACHED  |
                                           +-----------+
   * in Spring, when the transaction (and its EntityManager) ends

What Each State Means

StateHas id / row?In persistence context?Changes saved?
Transient (new)No row yet (id usually null)NoNo — Hibernate does not know it exists
Managed (persistent)YesYesYes, automatically at flush
DetachedYesNo (context closed or entity detached)No — needs merge
RemovedYes, until commitYes, scheduled for deletionDELETE at flush

Lifecycle, Simulated

Example

A small state machine that follows one product through every state, applying the same rules Hibernate enforces:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Context em = new Context();
        Product p = new Product("Boat Rockerz 450");
        em.print(p);                    // transient
        em.persist(p); em.print(p);     // managed
        em.detach(p);  em.print(p);     // detached
        try { em.remove(p); } catch (IllegalArgumentException e) { System.out.println("remove failed: " + e.getMessage()); }
        Product managed = em.merge(p);  em.print(managed);
        System.out.println("merge returned the same object? " + (managed == p));
        em.remove(managed); em.print(managed);
    }
}

enum State { TRANSIENT, MANAGED, DETACHED, REMOVED }

class Product {
    Long id; final String name;
    Product(String name) { this.name = name; }
}

class Context {
    private final Map<Long, Product> managed = new LinkedHashMap<>();
    private final Set<Long> removed = new TreeSet<>();
    private final Set<Long> knownIds = new TreeSet<>();   // rows that exist in the "database"
    private long nextId = 1;

    State stateOf(Product p) {
        if (p.id == null) return State.TRANSIENT;
        if (managed.get(p.id) == p) return removed.contains(p.id) ? State.REMOVED : State.MANAGED;
        return State.DETACHED;
    }
    void print(Product p) { System.out.println(p.name + " (id=" + p.id + ") -> " + stateOf(p)); }

    void persist(Product p) { p.id = nextId++; knownIds.add(p.id); managed.put(p.id, p); }
    void detach(Product p) { managed.remove(p.id); }
    void remove(Product p) {
        if (stateOf(p) != State.MANAGED) throw new IllegalArgumentException("Removing a detached instance Product#" + p.id);
        removed.add(p.id);
    }
    Product merge(Product p) {
        Product copy = new Product(p.name);   // Hibernate loads the row, then copies state onto it
        copy.id = p.id;
        managed.put(copy.id, copy);
        return copy;
    }
}

Output

Boat Rockerz 450 (id=null) -> TRANSIENT
Boat Rockerz 450 (id=1) -> MANAGED
Boat Rockerz 450 (id=1) -> DETACHED
remove failed: Removing a detached instance Product#1
Boat Rockerz 450 (id=1) -> MANAGED
merge returned the same object? false
Boat Rockerz 450 (id=1) -> REMOVED