Where should I distinct and sort data result from NHibernate?

I have a class with an one-to-many association, the collection was set to join fetch for performance concern, then the outer class getAll gave me a result with duplicate records. This problem is described as an ‘advanced problem’ in hibernate.org.

The solution is easy, adding a ResultSetTransformer to your ICretiria or IQuery.

criteria.SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer());

Problem was solved, but Ayende said, this is not a problem, it’s a feature! See details in his post, comment #9.

My distinct code using his idea looks like this:

IList<Item> itemList = …
ISet itemSet = new HashedSet( itemList as ICollection ) ;
itemList = itemSet as IList<Item>;
foreach( Item item in itemSet) {
itemList.Add(item);
}

return itemList

It brought 2 new problems to me, first ISet is not sorted, so I had to add a compareTo method to my domain object to implement

ArrayList.Adapter(itemList as IList).Sort();

Detail instruction can be found here. But this unique sorting naturally drove me thinking more about this, how about sorting by other property? Shouldn’t this be done by DAO? Including distinct.

I came to my solution then, adding a Order array to the GetByCriteria method in my GenericNHibernateDao. (Idea from <Hibernate in Action> Chapter 11)

public List<T> GetByCriteria(Order[] orders, params ICriterion[] criterion)
{
ICriteria criteria = NHibernateSession.CreateCriteria(persitentType);

foreach (ICriterion criterium in criterion)
{
criteria.Add(criterium);
}

foreach (Order order in orders)
{
criteria.AddOrder(order);
}

// distinct ICriteira
// not sure should I do this in persistence layer?
// Is it better to sort result in presenter?
// Or create a new method call GetDistinctResultByCriteria(…)
criteria.SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer());

return ConvertToGenericList(criteria.List());
}

public List<T> ConvertToGenericList(System.Collections.IList listObjects)
{
List<T> convertedList = new List<T>();

foreach (object listObject in listObjects)
{
convertedList.Add((T)listObject);
}

return convertedList;
}

Advertisements

2 thoughts on “Where should I distinct and sort data result from NHibernate?

  1. Hi, I’m testing GenericNHibernateDao and I done the same modification in CreateCriteria (althought it’s not perfect, it works)

    Does anyone have a better issue ?

    Best regards,

  2. Pingback: Blog de Rodrigo Juarez sobre TI » Blog Archive » Links sobre consultas con Criteria en NHibernate

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s