Reputation: 577
I am using NHibernate in my application and have the following situation. (Note that the situation here is much more simplified for the sake of understanding)
An object is queried from the database. It is edited and updated using Session.Update()
. The object is then Evicted from the Session (using Session.Evict(obj)
) before the transaction is committed. Expected result is that the changes are persisted to the database.
This used to work fine when I had my Id
column as a NHibernate identity
column.
Recently, we changed the Id column to be non-identity. As a result, the above scenario does not persist to the database unless I explicitly call Session.Flush()
before I Evict.
Can someone point/explain to me the reason for this behavior?
This link, NHibernate Session.Flush & Evict vs Clear, mentions something about Evict and the identity column, which to me is not very clear.
Upvotes: 2
Views: 5598
Reputation: 52735
Your workflow is not correct.
First, when you retrieve an object from the database, session.Update(entity)
does not do anything. Changes will happen automatically on Flush/Commit
Next, Evict
removes all knowledge the session has of the object, therefore it will not persist any changes applied to it. You should almost never use this method under normal conditions, which makes me think you are not handling the session correctly.
Third, the fact that using identity
causes inserts to happen immediately on Save
is a limitation, not a feature.
The correct workflow is:
using (var session = factory.OpenSession())
using (var transaction = session.BeginTransaction())
{
var entity = session.Get<EntityType>(id);
entity.SomeProperty = newValue;
transaction.Commit();
}
The exact structure (using
statements, etc) can change in a desktop application, but the basic idea is the same.
Upvotes: 9
Reputation: 30813
Identity forces NHibernate to immediatly save the entity to the database on session.Save()
non identity allows it to batch the inserts to send them as a whole. Evict will remove all information of the object from the session. So while with identity it forgets about the entity it is already in the database even if the session doesnt know.
to remedy that you can
Flushmode.Auto
(forces immediate flushing)session.Flush()
before Evict
which is the best option depends on the context
Upvotes: 2