Question
How can I resolve the Hibernate error: org.hibernate.NonUniqueObjectException when saving multiple user objects in the same session?
BaseHibernateDAO dao = new BaseHibernateDAO();
rtsession = dao.getSession(userData.getRegion(), BaseHibernateDAO.RTREQUESTS_DATABASE_NAME);
rttrans = rtsession.beginTransaction();
rttrans.begin();
rtsession.save(userObj1);
rtsession.save(userObj2);
rtsession.flush();
rttrans.commit();
rtsession.close();
Answer
The org.hibernate.NonUniqueObjectException occurs when you try to save or merge an entity into a Hibernate session, but another object with the same identifier already exists in that session. This situation commonly arises when dealing with multiple objects that are intended to represent the same database record, but Hibernate has already associated a different instance of that data with the session.
// Example of using merge instead of save
User userObj = //... fetch or create a user object
generatedUser = (User) rtsession.merge(userObj);
rtsession.flush(); // Many other operations can follow here.
Causes
- Multiple instances of the same entity with the same primary key are present in the session.
- You are trying to save or update an entity that was already persisted in the current session but with a different instance.
- Improper handling of session and transaction management, leading to stale instances lingering in the session.
Solutions
- Ensure that only one instance of the entity with a given primary key is associated with the session at a time.
- Use `session.merge()` instead of `session.save()` if you are unsure whether the object is already associated with the session.
- Consider using `session.clear()` carefully, as clearing the session will detach all entities. Ensure transactional boundaries are well managed.
Common Mistakes
Mistake: Not checking for existing object instances in the session before saving a new object with the same identifier.
Solution: Always check if the object is already present in the session using `session.contains(object)` before saving.
Mistake: Assuming session.clear() will automatically fix the NonUniqueObjectException without proper understanding of its consequences.
Solution: Use session.clear() with caution and ensure that you know what entities you are detaching.
Helpers
- Hibernate
- org.hibernate.NonUniqueObjectException
- Hibernate session save error
- Multiple user objects Hibernate
- Session management in Hibernate