NHibernate Forge
The official new home for the NHibernate community

NHibernate Mapping – Named queries <query/> and <sql-query/>

Queries are business logic, as such, they can be pretty complex, and they also tend to be pretty perf sensitive. As such, you usually want to have a good control over any complex queries. You can do that by extracting your queries to the mapping, so they don’t reside, hardcoded, in the code:

<query name="PeopleByName">
	from Person p
	where p.Name like :name
</query>

And you can execute it with:

using (var session = sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
	session.GetNamedQuery("PeopleByName")
		.SetParameter("name", "ayende")
		.List();
	tx.Commit();
}

PeopleByName is a pretty standard query, and executing this code will result in:

image

Now, let us say that we discovered some performance problem in this query, and we want to optimize it. But the optimization is beyond what we can do with HQL, we have to drop to a database specific SQL for that. Well, that is not a problem, <sql-query/> is coming to the rescue.

All you need is to replace the query above with:

<sql-query name="PeopleByName">
	<return alias="person"
					class="Person"/>
	SELECT {person.*}
	FROM People {person} WITH(nolock)
	WHERE {person}.Name LIKE :name
</sql-query>

And you are set. You don’t need to make any changes to the code, but the resulting SQL would be:

image

Fun, isn’t it?


Posted abr 17 2009, 12:55 a.m. by Ayende
Filed under:

Comments

Eddie Gems wrote re: NHibernate Mapping – Named queries <query/> and <sql-query/>
on 04-29-2009 8:37

What about an optimization via native SQL query loading of complex entityes? With one-to-one and one-to-many relations?

I have such long query and I need to set oracle hint to it (/*+ ORDERED */) but I don't want to rewrite query with 20 joins (I use not-lazy loading because I know that all the data I need on the entity page).

Ayende wrote re: NHibernate Mapping – Named queries <query/> and <sql-query/>
on 04-29-2009 9:07

Eddie,

Take a look at the loader element with query-ref

ayende.com/.../UsingNHibernateWithStoredProcedures.aspx

Joon wrote re: NHibernate Mapping – Named queries <query/> and <sql-query/>
on 08-19-2009 1:56

Hi Ayende,

 What if I want to include a db function that is not part of Person table but in a property of person class.

 For eg:

   <sql-query name="PeopleByName">

    <return alias="person" class="Person"/>

    SELECT {person.*}, length({person}.Name) as Length

    FROM People {person} WITH(nolock)

    WHERE {person}.Name LIKE :name

   </sql-query>

 The length is one of the property in the Person class, but the value can't be mapped with the above sql.

 It will work if I add a "Length" property in the mapping xml, but all other types of query will fail because this column can't be found in the table.

 Your help is greatly appreciated.

Regards,

Joon

Ayende wrote re: NHibernate Mapping – Named queries <query/> and <sql-query/>
on 08-19-2009 2:04

Joon,

That is why you have formula for on properties

Joon wrote re: NHibernate Mapping – Named queries <query/> and <sql-query/>
on 08-19-2009 3:02

Thanks a lot Ayende, you hit the point.

Powered by Community Server (Commercial Edition), by Telligent Systems