Reputation: 904
Consider the following scenario -
There are two tables (identical in schema) called ActiveIssue
and ResolvedIssue
. When an issue is active, it is in the ActiveIssue table and when the issue is resolved, it is moved to the ResolvedIssue table. Issues can be related to each other.
I have a method that does the following -
Before calling this method, I set session.setFlushMode(FlushMode.MANUAL)
to avoid the following scenario -
However, I observe that I run into a WrongClassException even with this logic in place. For instance, I get
org.hibernate.WrongClassException: Object with id: 123456 was not of the
specified subclass ... ActiveIssue
(loaded object was of wrong class ... ResolvedIssue)
I am using org.springframework.orm.hibernate3.support.HibernateDaoSupport
and I call Session session = getSession()
on this object. ActiveIssue and ResolvedIssue both derive from a base class called Issue
. I use the InheritanceType.TABLE_PER_CLASS
inheritance strategy on the base class, so ActiveIssue is mapped to the ActiveIssue table and ResolvedIssue is mapped to the ResolvedIssue table.
I don't understand why the WrongClassException occurs when I have explicitly set the FlushMode to MANUAL. Shouldn't the objects in the session be consistent?
Upvotes: 0
Views: 164
Reputation: 153780
The manual flush mode only affects your current session not any other competing thread. Every thread runs in Isolation thanks to Transactions. When you move an entity from a type to the other, it may be that the current Session holds a reference to the old type(e.g. ActiveIssue ) for a given id, while you try to persist/merge a different type(e.g. ResolvedIssue) entity with the same id.
make sure you always delete the old entry, flush the changes (even on AUTO) and then add the new type for the same id.
Upvotes: 1
Reputation: 4573
setFlushMode(...)
: Flushing is the process of synchronizing the underlying persistent store with persistable state held in memory.
In simple it will tell when to update/remove (sync.) data from memory which is taken from DB.
If go through FlushMode
you will come to knwo that setting FlushMode to MANUAL means memory will get sync. when you say session.flush()
.
Consider an scenario where One thread doing the work shifting an X issue from ActiveIssue to ResolvedIssue and at the same time another thread calling 1. Get related issues for an issue from ActiveIssue
So as per you before calling this you are setting FlushMode to MANUAL so it will not get sync. before query execution. AS per author
FlushMode.AUTO : The Session is sometimes flushed before query execution in order to ensure that queries never return stale state.
So when you query on table to Get related issues for an issue from ActiveIssue
an particular issue X (123456) is may be moved to ResolvedIssue by another thread. so the id 123456 is not of type ActiveIssue
so that your getting this exception
Upvotes: 1