Ok so we have a bit of an odd situation with Hibernate and I hope I can depict the problem correctly.
When we refresh an entity using session.refresh(), orphans can be left in the session that will then cause a staleobjectstateexception on the next flush.
Here's my example scenario:
- I have an entity called Human that has a cascading (Cascade All) association called Arm. One Human normally has 2 Arms.
- In our database we have Human1 that has Arm1 and Arm2.
- We have 2 users using the application (User 1 and User2).
- User1 and User2 both have open hibernate sessions (Session1 and Session 2). These open sessions contains the Human and its arms
- User1 from Session1 removes Arm1 from Human1 (sick bastard I know) and flushes.
- User2 from Session2 calls refresh() to reload the Human1 changes (makes other modifications) and flushes
Here's the problem: User2 will get a StaleOjectNotFoundException. Why? Because Arm1 is still in the session2. Yes we refreshed the Human1 but since Arm1 is "disconnected" it stays in the session...and when we try to refresh, hibernate isn't happy with this entity that was previously deleted.
Obviously my application is way more complex. We manage a very large tree of entities. We also use the OpenSessionInView paradigm as you probably guessed.
Here are a few ideas we had to solve the problem but we're not sure they're feasable or the best way to move forward:
- Is it possible to modify the Hibernate on flush listener to ignore those 'orphans'? Is there any way to know that they're 'orphans'...
- Can we have logic prepending the refresh that will go evict the orphans one way or another...? This is rather complicated when you have a large tree of dependant entities that are sometimes bi-directional.
- Can we make our own 'cascading' refresh that will somehow manage this?
Have any of you ever had to face this situation? Or do you have any idea how we can go to solve this problem?
Thanks a lot,
PS: We're using Hibernate 3.6