Hibernate saveOrUpdate trap for web developers and StaleStateException
Summary: Hibernate users should be aware of saveOrUpdate method if they continue to use the same persistent object even if a transaction failed at some point.
Details:
Suppose you have a persistent object bound to your web(like JSF) views. Entered some data (which will lead to a db ConstraintViolationException) and tried to save it (at your DAO service) by using saveOrUpdate method. As we expected, it will throw a ConstraintViolationException and you'll rollback the transaction.
Then, go back to the entry page, correct the wrong field value at the same object, and try to save it again. You'll get a StaleStateException since saveOrUpdate method assigned identifier values automatically to your new object when you attempt to save it first. Later, when the save operation failed, it didn't roll back your object's state to its initial state. The summary of the flow causing this error is as below;
In spite of the example working, transaction management is not working appropriately when it comes to both Hibernate and JBossCache participating of the same transaction. The reason is because at the time of writing this wiki, Hibernate did not allow to inject a JTA Transaction Manager which is not bound to JNDI. In the example, Hibernate creates a JDBC transaction and JBossCache a JTA transaction which are not linked together. To be able to make a Hibernate and JBossCache participant of the same JTA transaction in a standalone environment, customer code needs to be added to Hibernate to get around the JNDI/JTA coupling.