I\'m trying to understand the semantics of Session.persist()
, and exactly what the entity manager does with unsaved transient instances. What I want to achieve
Yes, this is part of the contract of Session.persist()
. According to Hibernate documentation, this is the order in which SQLs are executed:
- Inserts, in the order they were performed
- Updates
- Deletion of collection elements
- Insertion of collection elements
- Deletes, in the order they were performed
This order is part of the official Hibernate API, and applications rely on it when manipulating their entity graphs.
Putting changes that occurred after Session.persist()
immediately to INSERT
statements would break this contract and would cause problems in some use cases.
Let's suppose that we have a User
entity, and it is possible that two users are associated with each other in some way. Then we can insert the two in one transaction:
persist(user1);
persist(user2);
user1.setPartner(user2);
user2.setPartner(user1);
If everything was stored in INSERT
statements, then we would get foreign key constraint violation when persisting user1
.
In general, by ensuring that only the state that was passed to persist
ends up in INSERT
, Hibernate gives us more flexibility to satisfy underlying DB constraints.
I am not aware of any config with which this behavior can be changed. Of course, as you mentioned, you can restructure your code so that persist
is called after all the values are set, provided that no DB constraints are violated.