Exclusion and updating an object using NHibernate nulls all references

I am learning some unexpected actions with NHibernate that need more clarity. I create a new Request object and save it. I create another AuditLog object and add the query as a reference to AuditLog. I also save it. Now, if the request object is expelled from the session (for some reason) and updated again, the links in AuditLog will be NULLified in the database when the transaction is completed.

Any ideas on why this will happen?

If the request object is not created in the session, but is retrieved from the database and the same process is performed, the link is saved in AuditLog.

Sample code that has been edited for ease of understanding. If I remove session.Evict(request1)from the code, the test will pass. Using this code, when a session is closed, an additional request is launched in the database for a null request link in AuditLog.

//Session 1
var session = Resolve<IFullSession>().Session();
using (var tx = session.BeginTransaction())
{
    var request1 = new Request { Id = "REQ01" };
    request1.SetFieldValue("Type", "Stage1"); //Type is column in Request table
    session.Save("Request", request1);

    var auditLog1 = new AuditLog { Id = "LOG01" };
    auditLog1.SetFieldValue("Request", request1); //Request is reference column to AuditLog
    session.Save("AuditLog", auditLog1);

    session.Evict(request1);
    request1.SetFieldValue("Type", "Stage2");
    session.SaveOrUpdate("Request", request1);

    tx.Commit();
}
CreateInnerContainers(); // This closes earlier session.
//Session 2
var session2 = Resolve<IFullSession>().Session();
using (var tx = session2.BeginTransaction())
{
    var theLogObject = session2.Get<AuditLog>("LOG01");
    Assert.IsNotNull(theLogObject); // This is true
    Assert.IsNotNull(theLogObject.GetFieldValue("Request")); // This fails
    tx.Commit();
}
+3
source share
2 answers

You can access session objects and use what you like

session.GetSessionImplementation().PersistenceContext.EntityEntries

but if I were you i would make sure that i'm evicting the right object and spend some time on debuging. Knowing what is going on is better than searching for workarounds

foreach (var e in session.GetSessionImplementation().PersistenceContext.EntityEntries.Values.OfType<EntityType>().Where(<condition>))
{
    session.Evict(e);
}
+1
source

Calling “Save” in a session does not mean that your object is being written to the base database. It will persist in the current persistence context (your session).

If you remove this object from the context of persistence (what you do with the "eviction"), your session will not be able to save it to a flash (end of transaction).

session.Flush() session.Evict(request1) , .

NHibernate, , .

+1

All Articles