When attempting to update the same entity with two threads, the entity is retrieved from the DB in both threads. First thread completes the update, but the second thread gets a StaleStateException Here are the steps which Hibernate performs to update the entity in the second thread, starting from the point when it attempts to persist:
1. A PreparedStatement is constructed.
2. PreparedStatement is executed using the NonBatchingBatch.
3. StaleStateException is thrown by the second thread.
4. PreparedStatement is closed.
5. Transaction is rolled back.
6. I attempt to retry the update...
7. Entity is re-fetched from the DB.
8. Entity fields are updated.
9. Same session attempts to persist the entity to the DB.
10. NonBatchingBatch is still present in the JdbcCoordinator
12. AbstractEntityPersister#update:3049 gets the same NonBatchingBatch
13. AbstractEntityPersister attempts to execute previously closed PreparedStatement
14. java.sql.SQLException: Invalid state, the PreparedStatement object is closed.