The PreUpdateEvent Listener gets called like this
bool OnPreUpdate(PreUpdateEvent @event);
and the complete information about the entity is passed as the @event
parameter, which is of type class PreUpdateEvent
. So we do have access properties:
/// <summary> The entity involved in the database operation. </summary>
public object Entity { get; }
/// <summary> The id to be used in the database operation. </summary>
public object Id { get; }
/// <summary>
/// Retrieves the state to be used in the update.
/// </summary>
public object[] State { get; }
/// <summary>
/// The old state of the entity at the time it was last loaded from the
/// database; can be null in the case of detached entities.
/// </summary>
public object[] OldState { get; }
There are all information we can get, latest changes (State
) and previous values (OldState
)
In this phase (event) we cannot call the session.get()
... because there is already "the updated" object. Session would NOT in this case in target the DB.
As the comment says: the OldState, could be NULL if the object comes from external world (client, service layer) and is passed to session via Update()
. To avoid this, we can call session.Merge(ourInstance)
which will fix lot of issues. See: 9.4.2. Updating detached objects
EXTEND: How does the OldState work?
1) Either we are loading object via sessin.GetById(id)
. Session has hands on it, while we are amending that instance. Finally, we call session.Flush()
to do UPDATE statement in DB. In this case, NHibernate does have everything under its control... the OldState
is properly filled.
2) Or we do recieve data from external (not session
) world, represented by detached instance. In this case, NHibernate was not able to track changes. It only has the latest information passed via session.Update(instance)
, and on Flush() it does trigger the PreUpdate event, but without the old state.
In that case, we can call session.Merge(instance)
instead of Update()
and NHibernate will load the object from DB (and therefore will have its previous values), update them with the latest settings coming with the merging instance, and trigger the PreUpdate
event with full info.