What's new? | Help | Directory | Sign in
Google
                
Search
for
Updated Apr 04, 2008 by fabiomaulo
Labels: Phase-Implementation
LesTroisMousquetaires  
DetachedCriteria, DetachedQuery, DetachedDynQuery; Les trois mousquetaires

Introduction

Many applications need to create feching criteria where the NHibernate session is not available. Normally we create a serializable object that represent criteria (objCriteria) and we send that object through several layers. Some application parse the objCriteria in the DAO where de NHSession is available.

Some other application implements a GenericNHibernateDAO with methods that work using some basic generic information to create the fetching criteria. For example a generic implementation can look like these:

public IList FetchByCriteria(ICriterion[] criterion)
public IList FetchByQuery(string hql)

In many cases this is not enough because we need parameters values, so we can see some other implementation like these:

public IList FetchByCriteria(ICriterion[] criterion, IDictionary parameters)
public IList FetchByQuery(string hql, IDictionary parameters)

Look this enough ? No. In some other cases we need to set others ICriteria or IQuery properties, for example FirstResult and MaxResults for pagination.

We need something like ICriteria and IQuery but without the NHSession.

To solve the problem one time at all we have: Les trois mousquetaires

Detached Criteria

DetachedCriteria born in Hibernate and was ported to NHibernate 1.2.0Alphax. In the NH1.2.0 you have available the result of this port. In uNhAddIns we extract the DetachedCriteria to extend it for pagination. In the NH2.0 you have a more powerful version of DetachedCriteria that include a TransformToRowCount so create a paginable rows counter is a joke.

Detached Query

DetachedQuery was the first experience of iteration between NH and our laboratory. It born in NH2.0, was extracted to use it in uNhAddIns, modified for real world use and come back to NH with modifications. DetachedQuery work like DetachedCriteria but for queries. Queries mean the various implementation of IQuery; basically an HQLstring, a named HQL or named SQL.

Detached Dyn Query

Before explain what DetachedDynQuery is, I would like to spend some words:

Before think to use a dynamic query you must study the ICriteria (note that I said before think and not "before use")

DetachedDynQuery is a IDetachedQuery based on a dynamic HQL. A dynamic HQL is an HQL string created with special clases that mimic HQL clause.

Select s = new Select("f.Name, f.Description, b.Descriptoin").From("Foo f join f.Bar b").Where("f.Name like :pName");

The target of dynamic query is to know each part of HQL to allow clause injection. Normally you have the a know from clause with or without a know select and you need to inject the HQL with a special order by clause and/or a special where clause. Take a look to uNhAddIns.Test.DynamicQuery.DynQueryFixture.CommonUse() for details.

For various reason some developer prefer to construct a HQL string at runtime instead to use ICriteria. I'm not a good philosopher, so for who want/prefer/need HQL string construction at runtime are dynamic query.

The DetachedDynQuery know each HQL part so it can easy transform the HQL to the correspondent row count (see uNhAddIns.DynQuery.DetachedDynQuery.TransformToRowCount()).

DetachedDynQuery is a IDetachedQuery so it can be used like any other implementation of IDetachedQuery and this mean that it can be used for pagination too. The PaginableDynQuery is a paginable rows counter because the DetachedDynQuery can be transformed to it's rows counter.

How does your GenericNHibernateDAO look now?

Probably like this:

public IList<T> Find(DetachedCriteria criteria)
{
	return criteria.GetExecutableCriteria(Session).List<T>();
}

public IList<T> Find(IDetachedQuery query)
{
	return query.GetExecutableQuery(Session).List<T>();
}

public virtual IPaginable<T> GetPaginable(DetachedCriteria criteria)
{
	return new PaginableCriteria<T>(Session, criteria);
}

public virtual IPaginable<T> GetPaginable(IDetachedQuery query)
{
	return new PaginableQuery<T>(Session, query);
}

With two methods you have full power to fetch what you want. With other two methods you have full power to fetch what you want, and paginate it.

An example is available in uNhAddIns.Test.aReposEmul.GenericNHibernateDAO<T, TId>.

Conclusions

Les trois mousquetaires give us a powerful way to simplify our generic DAO and to create others powerful resources to work with NH (the pagination was the first example).

Fabio Maulo


Sign in to add a comment