Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Attaching a disconnected object to an NHibernate session; best practice?

Tags:

c#

nhibernate

My repository works in a UnitOfWork model; all operations, whether retrieval or persistence, must be performed within the scope of an IDisposable UnitOfWork token object, which behind the scenes is associated with a Session that performs the work requested. So, the basic pattern is:

using (var uow = repo.BeginUnitOfWork())
{
   try
   {
      //DB operations here; all repo methods require passing in uow.
      ...
      repo.CommitUnitOfWork(uow);
   }
   catch(Exception)
   {
      repo.RollbackUnitOfWork(uow);
      throw;
   }
}

I've also implemented some wrapper methods that allow you to specify a lambda or delegate that will be executed in this framework, relieving the need to implement all this scaffolding every time.

The problem I'm having is that using this model, code must "know" what the user needs, and eager-load it using NHUtil.Initialize() within the UnitOfWork. Once the UOW is disposed at the end of the using block, the Session associated with any PersistentBags is closed, and so they cannot be evaluated. As eager-loading everything up front is not always feasible and kind of defeats the purpose of a lazy-loading ORM, I am implementing an Attach() method.

Here's the question; In the absence of a built-in ISession.Attach() method, there are three methods I've seen recommended to associate an object with a new Session. Which of them is the best practice to get the job done?

A:

if(!Session.Contains(domainObject))
    Session.Update(domainObject);

B:

Session.Merge(domainObject);

C:

Session.Lock(domainObject, LockMode.None);
like image 271
KeithS Avatar asked Dec 14 '10 21:12

KeithS


1 Answers

D: None of the above. Effectively disabling lazy-loading by keeping your UOW too short and defeats the purpose of a lazy-loading ORM. The fact that you have to re-associate disconnected objects as normal operations means that your unit of work boundaries are wrong.

Merge, Update, and Lock all have different purposes. If you're stuck with your current architecture then Lock is probably what you want.

  • Update - associates a changed object
  • Lock - associates an unchanged object
  • Merge - if the object exists in the current session then it is updated with changes from the merged object, otherwise it's the same as Lock
like image 159
Jamie Ide Avatar answered Sep 22 '22 06:09

Jamie Ide