The Inquisitive Coder – Davy Brion's Blog

Trying to walk that thin line between intelligence and ignorance

NHibernate and Future Queries

Posted by Davy Brion on January 25th, 2009

As some of you already know, i’m a big fan of avoiding excessive roundtrips by batching queries and/or service calls. For NHibernate, i wrote the QueryBatcher class which makes this pretty easy to do. Ayende recently added a much easier approach for this to NHibernate.

Take a look at the following code:

            using (ISession session = sessionFactory.OpenSession())

            {

                // this executes the first query

                var categories = session.CreateCriteria(typeof(ProductCategory)).List();               

                // this executes the second query

                var suppliers = session.CreateCriteria(typeof(Supplier)).List();

 

                foreach (var category in categories)

                {

                    // do something

                }

 

                foreach (var supplier in suppliers)

                {

                    // do something

                }

            }

This is a really trivial example, but it should be more than sufficient. It simply executes two very simple queries and loops through the results to do something with each returned entity. The problem, obviously, is that this hits the database twice while there really is no good reason for doing so.

With the new Future feature we can rewrite that code like this:

            using (ISession session = sessionFactory.OpenSession())

            {

                // this creates the first query

                var categories = session.CreateCriteria(typeof(ProductCategory)).Future<ProductCategory>();

                // this creates the second query

                var suppliers = session.CreateCriteria(typeof(Supplier)).Future<Supplier>();

 

                // this causes both queries to be sent in ONE roundtrip

                foreach (var category in categories)

                {

                    // do something

                }

 

                // this doesn't do anything because the suppliers have already been loaded

                foreach (var supplier in suppliers)

                {

                    // do something

                }

            }

Apart from the comments, did you spot the difference? Instead of calling ICriteria’s List method (which causes the query to be executed immediately), we call ICriteria’s Future method. This returns an IEnumerable of the type you provided to the Future method. And this is where it gets interesting. Instead of executing the queries immediately, the queries are added to an instance of NHibernate’s already existing MultiCriteria class. Only once you enumerate through one of the retrieved IEnumerables will all the (queued) Future queries be executed, in a single roundtrip. Once they are executed, their result is final (as in: enumerating through the IEnumerable will not cause the query to be executed again).

The example used here is obviously very trivial, but you can use this with any ICriteria so you can very easily start batching your complex queries as well. The kind of query doesn’t really matter, as long as it’s an ICriteria instance.

This feature will be available in NHibernate 2.1, or if you’re using the trunk you can use it starting with revision 3999.

8 Responses to “NHibernate and Future Queries”

  1. Future<T> Queries with HQL and Criteria at Dario Quintana Says:

    [...] examples adapted from Davy Brion posts [1] and [...]

  2. Future<T> Queries with HQL and Criteria - NHibernate blog - NHibernate Forge Says:

    [...] examples adapted from Davy Brion posts [1] and [2]. Posted ene 30 2009, 01:10 p.m. by Dario Quintana Filed under: querying, HQL, Criteria, [...]

  3. The Inquisitive Coder - Davy Brion’s Blog » Blog Archive » NHibernate’s Future Queries And Their Fallback Behavior Says:

    [...] blogged about NHibernate’s Future queries a couple of times already. But as you know, NHibernate aims to offer you a way to write your code completely [...]

  4. Elegant Code » Why Future<T> should be in your future Says:

    [...] Former ECer Davy Brion, as always, does an excellent job of demonstrating usage of the feature here so I am not going to rehash that. What I am going to focus on here if the [...]

  5. Prasobh Says:

    u have mentioned in the above eg with Using keyword

    using (ISession session = sessionFactory.OpenSession())

    will the session object here be disposed once it leaves the using Scope or will i have to manually close the session object by telling Session.Close()

  6. Davy Brion Says:

    @Prasobh

    calling Dispose on the ISession interface will indeed close the session

  7. stepan Says:

    How about the names of parameters in Future Queries? I have a big problem in combining queries with the same parameter name.

  8. Davy Brion Says:

    @stepan

    that’s a problem that only occurs with HQL queries… but it has been fixed already and the fix will be in NH3.0:
    http://nhjira.koah.net/browse/NH-2084

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>