Issue
I have a requirement to frequently synchronize a large collection of detached entities to the database, and am wanting to do so with Session.saveOrUpdate()
. These entities are of the same type and have several OneToMany CascadeType.ALL associations.
This is currently a performance hotspot that slows down my application (it's taking minutes and I need it to take seconds). To solve this, I've looked to Hibernate's second level cache (with EhCache).
My problem is that each time I attempt a saveOrUpdate
on these entities, Hibernate's statistics show I accumulate many puts, but always 0 hits and 0 misses. And (interestingly) the puts continue to accumulate each time I attempt the saveOrUpdate
again.
The good news is I have been able to refactor my application to use Session.merge()
instead of saveOrUpdate
. With this, I am successfully hitting the second level cache and achieving a noticeable performance improvement, and my detached entities and their associations are synchronized to the database correctly.
My question is why isn't the second level cache hit when I invoke saveOrUpdate
? If I could use saveOrUpdate
, my code changes would have been minimal. I've glanced at the Hibernate source code's saveOrUpdate
implementation and found this TODO
that seemingly (without fully understanding the code) bypasses the second level cache:
Is that the answer? This capability just hasn't been implemented yet? My Hibernate version is 5.2.10, and I confirmed the current Hibernate version (6.1.2) still contains to the TODO.
Solution
Since saveOrUpdate
was deprecated in 6.0 with merge
being the replacement for it, the migration is good. This method will be removed in the future and there will be no further feature development for it.
Answered By - Christian Beikov
Answer Checked By - Terry (JavaFixing Volunteer)