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,026 | Comments: 44,842

filter by tags archive

NH Prof new featureSuperfluous update

time to read 7 min | 1335 words

Yes, I am aware that I said that I would only have two more feature for NH Prof before releasing. But I am currently being held hostage by the new features fairy, and negotiations over a feature freeze seems to have gotten to a stand still. Beside, it is a neat feature.

The actual feature is quite simple. Let us say that we have the following model:


Notice that this is a very common case of bidirectional association, and this is mapped to the following table model:


Notice that while on the object model this is a bidirectional association and is maintained by two different places, it is maintained on a single place in the database.

This is a a very common case, and quite a few people get it wrong. By default, NHibernate has to assume that it must update the column on both sides, so creating a new post and adding it to the Blog’s Posts collection will result in two statements being written to the database:

   1: INSERT INTO Posts(Title,
   2:                   Text,
   3:                   PostedAt,
   4:                   BlogId,
   5:                   UserId)
   6: VALUES     ('vam' /* @p0 */,
   7:             'abc' /* @p1 */,
   8:             '1/17/2009 5:28:52 PM' /* @p2 */,
   9:             1 /* @p3 */,
  10:             1 /* @p4 */);
  11: select SCOPE_IDENTITY ( )
  13: UPDATE Posts
  14: SET    BlogId = 1 /* @p0_0 */
  15: WHERE  Id = 22 /* @p1_0 */

As you can see, we are actually setting the BlogId to the same value, twice.

Now, there is a very easy fix for this issue, all you have to do is to tell NHibernate on the Blog’s Posts mapping that this is a collection where the responsibility for actually updating the column value is on the other side. This is also something that I tend to check in code reviews quite often. The fix is literally just specifying inverse=’true’ on the <many-to-one> association.

And now NH Prof will detect and warn about such cased:



This is also the first case in which I am starting to do much more in depth analysis of what is actually going on with NHibernate. I planned to do this sort of thing after the v1.0 release, but as I said, I am held hostage by the new features fairy, and this is my negotiation technique :-)

More posts in "NH Prof new feature" series:

  1. (09 Dec 2010) Alert on bad ‘like’ query
  2. (10 Dec 2009) Filter static files
  3. (16 Nov 2009) Exporting Reports
  4. (08 Oct 2009) NHibernate Search Integration
  5. (19 Aug 2009) Multiple Session Factory Support
  6. (07 Aug 2009) Diffing Sessions
  7. (06 Aug 2009) Capturing DDL
  8. (05 Aug 2009) Detect Cross Thread Session Usage
  9. (22 May 2009) Detecting 2nd cache collection loads
  10. (15 May 2009) Error Detection
  11. (12 May 2009) Queries by Url
  12. (04 Feb 2009) View Query Results
  13. (18 Jan 2009) Superfluous <many-to-one> update
  14. (18 Jan 2009) URL tracking
  15. (10 Jan 2009) Detecting distributed transactions (System.Transactions)
  16. (06 Jan 2009) The Query Cache
  17. (05 Jan 2009) Query Duration
  18. (24 Dec 2008) Unbounded result sets
  19. (24 Dec 2008) Row Counts


Tobin Harris

Great feature! I love the direction this is taking, and that NHProf can start to actually teach people useful information about NHibernate. That also gives them 2 reasons to buy your product - to help find possible performance problems and also to learn how to resolve them.

Kenny Eliasson

This is awesome! One of the first issues I believe anyone has with NHibernate is the mapping of collections. Great work! Keep it up


I really like the alerts NHProf is getting. So far, profiling (such as JetBrains dotTrace or RedGate ants) usually 'pauses' the moment the application (or depended component) performs a database query. All we know is that DbCommand.ExecuteQuery took 120ms. We offen tent to try to minimize those performance bumps. Because we are confidant that our queries are very optimized, that those areas are usually skipped during profiling sessions. Most developers use tools like Microsoft query analyzer to see if they have made the proper indexes.

Because the update is unnecessary, such a alert can be a (literally) real time safer when you're dealing with a customer <--> order association where both tables have more than 10 million records.

In today's applications databases play an important part. Compared to the profilers mentioned above 200 (or less) euros for a query profiler/debugger/optimizer is a very good bargain. A must have for every .net developer!


"The fix is literally just specifying inverse=’true’ on the <many-to-one association."

Am I missing something here or just miss reading it, say in my example Inverse="true" goes on my set mapping:


This is the correct side right? I think of this as the one-to-many side but I may have just misinterpreted my definitions :).




Does this profiler work with the Java version of Hibernate?

Ayende Rahien


There is a high likelyhood that it would,as a matter of fact.

Never tested it, though.

Comment preview

Comments have been closed on this topic.


No future posts left, oh my!


  1. Technical observations from my wife (3):
    13 Nov 2015 - Production issues
  2. Production postmortem (13):
    13 Nov 2015 - The case of the “it is slow on that machine (only)”
  3. Speaking (5):
    09 Nov 2015 - Community talk in Kiev, Ukraine–What does it take to be a good developer
  4. Find the bug (5):
    11 Sep 2015 - The concurrent memory buster
  5. Buffer allocation strategies (3):
    09 Sep 2015 - Bad usage patterns
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats