Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,124 | Comments: 45,483

filter by tags archive

NHibernate – Executable DML

time to read 4 min | 712 words

This is a new feature of NHibernate that Fabio has recently ported. Using the same model that I have talked about before:


With the following schema:


The feature is basically this, NHibernate can now execute set based operation on your model. This include all Data Modification Language operations, so we are talking about Update, Insert and Delete. Let us make things a bit interesting and talk about the following statement, which hopefully will make things clearer:

s.CreateQuery("update Owner o set o.Name = 'a' where o.Name = 'b'")

Executing this code will make NHibernate execute the following SQL statements:







As you can see, we have executed a very simple query against the model, which translate to a fairly complex data model (needing to update three separate tables. We can also see that we are doing significant effort to maintain the illusion of a single query (that is why we need the temp table here).

But we are not limited to just updates, we can also do deletes:

s.CreateQuery("delete Owner o where o.Name = 'b'")

Which result in:







I think that by now you are already familiar with the pattern :-)

As for insert statements, they are supported as well, but there are some limitations. In particular, you have to use an identifiers generation strategy that can generate identifiers in the database (sequence or identity), and there are some limitation on how you can make this work in several complex hierarchies. Using a simple Table Per Class, the following HQL works:

s.CreateQuery("insert into Individual (Name, Email) select i.Name, i.Email from Individual i")

And generates:


All in all, this is a really awesome feature.

Thanks, Fabio.


len smith

This is amazing.

How does this affect objects in the first-level cache? Are they all automatically updated or evicted from the session?

Fabio Maulo

The session-cache is not affected because executable queries are not loading entities.

Ayende Rahien

As Fabio said, this does NOT affect the session cache, but it DOES affect the 2nd level cache.

Andres G. Aragoneses

So this is not HQL?

How complex would it be to try to make NHibernate update the session cache? Would that kill performance?

Andrey Shchekin

Looks good (actually more like a mandatory feature, at least for updates). But why you use string-based HQL so often in your samples? From the author of NHQG this is surprising.

Ayende Rahien


Those things are happening in the database, outside of NHibernate. We don't want to update the session cache, it would be incredibly complex, and break the state equality between NH & the DB

Ayende Rahien


Because the strings are the simplest thing that work, and anything else turned out to be way too much hassle

Peter Morris

What if someone later adds setter code to o.Name? What if the data update breaks invariants?

I assume this is something which should really be used quite rarely.

pete w

This is major!

Good to know. En-masse updates has always been the achilles heel of ORMs. I write stored procedures for this kind of thing, and then invalidate all caches/sessions after the fact.

What would be nice is to do the same thing for en-masse deletes. Large-scale deletions are a common use case and it would be nice to do without loading each object, or falling back on a SPROC.

Nice work fabio! thank you for all the help, you rock

Ayende Rahien


Um, don't use that that if you care about the setter side affects?

Peter Morris


That's my point. When you first use some DML in an app there might not be side affects, but later on some may be introduced and the DML will bypass them.

I'm just pointing out that this is really something I think should be used in moderation, and with great care :-)



Ayende Rahien


Not really. It is not something that you would use for everything, but it is something that can be extremely useful in many aspects.

In particular, it can make certain tasks that would require you to write SQL so much easier.

Since obviously there is a disconnect between those sort of operations and in memory ones, it is pretty clear what is going to happen

Comment preview

Comments have been closed on this topic.


  1. RavenDB 3.5 whirl wind tour: I’ll find who is taking my I/O bandwidth and they SHALL pay - 5 hours from now
  2. The design of RavenDB 4.0: Physically segregating collections - about one day from now
  3. RavenDB 3.5 Whirlwind tour: I need to be free to explore my data - 2 days from now
  4. RavenDB 3.5 whirl wind tour: I'll have the 3+1 goodies to go, please - 5 days from now
  5. The design of RavenDB 4.0: Voron has a one track mind - 6 days from now

And 12 more posts are pending...

There are posts all the way to May 30, 2016


  1. RavenDB 3.5 whirl wind tour (14):
    02 May 2016 - You want all the data, you can’t handle all the data
  2. The design of RavenDB 4.0 (13):
    03 May 2016 - Making Lucene reliable
  3. Tasks for the new comer (2):
    15 Apr 2016 - Quartz.NET with RavenDB
  4. Code through the looking glass (5):
    18 Mar 2016 - And a linear search to rule them
  5. Find the bug (8):
    29 Feb 2016 - When you can't rely on your own identity
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats