Search code examples
nhibernatefluent-nhibernatehqlfetching-strategy

Nhibernate producing proxy despite HQL fetch


I have the following HQL statement:

select distinct t from TaskEntity as 
inner join fetch t.Case as c
inner join fetch c.Client as client 
inner join fetch c.Matter as matter

However, despite Matter having a FETCH against it, it's still returning as a proxy.

My mapping for this object is below

References(x => x.Matter).Columns(new[] {"c_client","c_matter" });

I've tried using JOIN on this, but my issue I'm going from 1 to 2 columns, so it wouldn't accept the mapping.

Any thoughts?

Thanks,


Solution

  • I worked out the problem that was causing this issue.

    It also resolves to Composite IDs!

    Earlier in the project Nhibernate was warning that I was not overriding Equals and GetHashCode, to circumvent lots of code changes, and to promote code re-use I made a CompositeBaseEntity class:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Case.Infrastructure
    {
        public class BaseCompositeEntity : BaseEntity
        {
            public override int GetHashCode()
            {
                return base.GetHashCode();
            }
    
            public override bool Equals(object obj)
            {
                return base.Equals(obj);
            }
        }
    }
    

    This class, puts back in place what Nhibernate was telling me to avoid! As there are two keys to compare equality against, we MUST override the Equals & GetHashCode() methods to become something like:

    public override bool Equals(object obj)
            {
                if (obj == null)
                    return false;
                var t = obj as ClientMatterEntity;
                if (t == null)
                    return false;
                if (AccountNumber== t.ClientAcconuntNumber && CaseNumber == t.CaseNumber)
                    return true;
                return false;
            }
    

    This way, Nhibernate knows exactly how comparison should be done, and then knows if it has that object in a first-level cache (which it will, as we specified fetch).

    More information can be found here: http://nhforge.org/blogs/nhibernate/archive/2010/07/01/nhibernate-and-composite-keys.aspx