There is a famous exception:
org.hibernate.StaleObjectStateException: Row was updated or deleted by
another transaction (or unsaved-value mapping was incorrect): [my.Entity#123456]
This is a very familiar situation when "row was updated or deleted by another transaction".
But what means another possibility - "unsaved-value mapping was incorrect"? And how to reproduce such situation intentionally?
Grails 2.2.0
For a description of unsaved-value see http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/mapping.html#mapping-declaration-id:
unsaved-value (optional - defaults to a "sensible" value): an
identifier property value that indicates an instance is newly
instantiated (unsaved), distinguishing it from detached instances that
were saved or loaded in a previous session.
Hibernate needs this in rare cases, when saveOrUpdate() is not able to determine if the entity is new or detached.
If an entity is determined by means of your unsaved-value as detached, but is instead new, then hibernate can't compare the version numbers (because the entity just doesn't exist in the database). But Hibernate can't know if your unsaved-value mapping is not correct or the entity has been deleted in another transaction. This is described in org.hibernate.StaleStateException as well:
Thrown when a version number or timestamp check failed, indicating
that the Session contained stale data (when using long transactions
with versioning). Also occurs if we try delete or update a row that
does not exist.