R – nHibernate (a==b) equality

nhibernate

I'm currently using nHibernate and having a problem where two objects loaded separately but representing the same entity in the database do not have equal references.

See the following section of code for example:

CrudRepository<Customer> cr1 = new CrudRepository<Customer>();
Customer c1 = cr1.GetById(new Guid("0D19B0F0-CA41-4D4B-9FB9-9CF600F86A4B"));

CrudRepository<Customer> cr2 = new CrudRepository<Customer>();
Customer c2 = cr2.GetById(new Guid("0D19B0F0-CA41-4D4B-9FB9-9CF600F86A4B"));

if (c1.Equals(c2))
    MessageBox.Show("SAME!");   // True.

if (c1.GetHashCode().Equals(c2.GetHashCode()))
    MessageBox.Show("SAME!");   // True.

if (c1 == c2)
    MessageBox.Show("SAME!");   // False.

My interpretation of the nHibernate documentation lead me to believe that once you override the Equals() and GetHashCode() methods, nHibernate can load entities into the same reference.

This is the line I am referring to:

This only applies if these objects are loaded in two different ISessions,
as NHibernate only guarantees identity
( a == b , the default implementation
of Equals()) inside a single
ISession
!

I understand that (c1 == c2) is comparing the references of objects loaded at different times. However, I thought (and hoped) that nHibernate would automatically track pre-loaded references and update them accordingly.

Is this not true?

Or is there something I am doing wrong?

Thanks 🙂

NOTE: I use the singleton pattern to keep the same session throughout the application.

Edit: Every time I perform a CRUD task I use this NHibernateHelper class to get the single instance of the same session builder. This was an example piece of code.

public T GetById(Guid guid)
{
    using (ISession session = NHibernateHelper.OpenSession())
    using (ITransaction transaction = session.BeginTransaction())
    {
        return session.Get<T>(guid);
    }
}

And this is my helper class:

public class NHibernateHelper
{
    private static ISessionFactory sessionFactory;

    private static ISessionFactory SessionFactory
    {
        get
        {
            if (sessionFactory == null)
            {
                var configuration = new Configuration();
                configuration.Configure();
                configuration.AddAssembly(typeof(Customer).Assembly);
                sessionFactory = configuration.BuildSessionFactory();
            }
            return sessionFactory;
        }
    }

    public static ISession OpenSession()
    {
        return SessionFactory.OpenSession();
    }
}

Best Answer

You are creating a new session on every request (this is what your NHibernateHelper.OpenSession() method does) and nHibernate only guarantees reference equality within one session. Once you make sure that your requests are within the same session, the result of the two call will be the same object.

Related Topic