✅ Short Answer
Session.save()
inserts a new object into the database; if the object has an existing identifier, it will throw an error or overwrite unexpectedly.Session.merge()
updates an existing object or saves it if it doesn’t exist, even if the object is detached (not associated with the current Hibernate session).
🔎 Detailed Explanation
Session.save()
- Immediately persists a transient (new) entity to the database.
- Assigns and returns a new identifier.
- The entity becomes persistent in the current session.
- Using
save()
with an existing ID can cause duplicate key errors.
Session.merge()
- Designed for detached entities: copies the state of the object to the persistent entity in the current session.
- Updates existing data if the ID already exists.
- Returns the managed instance — use this going forward.
- Prevents duplicate inserts by intelligently updating or inserting as needed.
🧑💻 Code Example
// Using Session.save()
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
MyEntity entity = new MyEntity();
entity.setName("New Entity");
session.save(entity); // Inserts a new row
tx.commit();
session.close();
// Using Session.merge() with a detached entity
MyEntity detachedEntity = ...; // Loaded in an old session
Session newSession = sessionFactory.openSession();
Transaction tx2 = newSession.beginTransaction();
MyEntity managedEntity = (MyEntity) newSession.merge(detachedEntity); // Updates existing or inserts new
tx2.commit();
newSession.close();
📊 Quick Comparison Table
Feature | save() | merge() |
---|---|---|
Entity state | Transient | Detached or transient |
Operation | Insert new row | Update existing or insert new |
Identifier exists | May throw error / duplicate | Updates existing or creates new |
Return value | void (identifier assigned) | Managed persistent instance |
Use case | New objects | Reattaching detached objects |
📌 Key Takeaways
✅ Use save()
only for new entities without existing IDs.
✅ Use merge()
to reattach detached entities or safely update existing ones.
✅ merge()
helps avoid duplicate key issues when working with objects from previous sessions.
✅ Always use the returned instance from merge()
for further operations.
💡 Extra Insight: Session vs. Entity State
- In Hibernate, an entity can be:
- Transient — not associated with any session, no DB record yet.
- Persistent — associated with an open session, changes automatically tracked.
- Detached — previously persistent but the session is closed or cleared; no longer tracked.
save()
only works reliably on transient entities.merge()
handles detached entities, making it critical when you need to re-sync objects after session boundaries.