问题
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,
回答1:
Be aware that you must also provide a correct GetHashCode implementation.
Your Equals implementation is also not great.
Furthermore, both methods should return 'static' values. I have not seen your class but is should be something like:
public class TaskEntity
{
public int AccountNumber { get; protected set; }
public int CaseNumber { get; protected set; }
public Client Client { get; set; }
public Matter Matter { get; set; }
public TaskEntity(int accountNr, caseNr)
{
AccountNumber = accountNr;
CaseNumber = caseNr;
}
protected TaskEntity() {} // Needed for NHibernate proxies
}
I really recommend that you put your component id's in seperate classes when possible.
Furthermore, read the following article about override Equal as your current implementation is probably flawed : http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx especially understand the part regarding inheritance and base types.
回答2:
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
来源:https://stackoverflow.com/questions/10176862/nhibernate-producing-proxy-despite-hql-fetch