Question
What causes Hibernate's NonUniqueObjectException, and how can it be resolved?
Session session = sessionFactory.openSession();
Object entity1 = session.get(MyEntity.class, ID1);
Object entity2 = session.get(MyEntity.class, ID2);
// Attempt to update with non-unique entity
session.update(entity1); // This may throw NonUniqueObjectException if entity2 is also attached.
Answer
Hibernate's NonUniqueObjectException is thrown when an attempt is made to associate multiple instances of an entity class with the same identifier to a single session. This situation often arises in scenarios involving persistent entities that are managed by session context, leading to conflicts.
// Correct handling of an entity
session.beginTransaction();
MyEntity entity = session.get(MyEntity.class, id);
entity.setSomeProperty(newValue);
// Use merge instead of update in some cases
session.merge(entity);
session.getTransaction().commit();
Causes
- Multiple instances of the same entity class are being associated with the session.
- An entity is already attached to the session and another instance with the same identifier is being referenced.
- Improper management of session states, particularly in long-running transactions.
Solutions
- Ensure that only one instance of an entity with a particular identifier is attached to the session.
- Use session.clear() to detach all current entities when starting a new transaction.
- Consider using merge() instead of update() for detached instances.
- Manage entity states carefully to avoid re-attaching entities unintentionally.
Common Mistakes
Mistake: Not using session.clear() before starting a new transaction in a long-running session.
Solution: Always clear your session when switching contexts to avoid NonUniqueObjectException.
Mistake: Attaching multiple instances of the same entity in a single session.
Solution: Ensure only one reference of any entity with a specific identifier is active within a session.
Helpers
- Hibernate
- NonUniqueObjectException
- Hibernate error handling
- session management in Hibernate
- merge Hibernate
- update Hibernate
- Java Hibernate best practices