Ayende @ Rahien

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

ayende@ayende.com

+972 52-548-6969

, @ Q c

Posts: 18 | Comments: 79

filter by tags archive

Case Sensitive Optimization

time to read 2 min | 335 words

I am doing some optimization work lately, and I managed to take a page down to three DB requests per page load, but I couldn't get it to less than that, and it really annoyed me. The problem was that accessing a certain properly on an entity would cause a lazy load, even though I have explicitly told it to eagerly load that.

That was... annoying.

Eventually I got rid of all the "it can't be!" mentality and looked at what was going on, the problem was that I was looking for NHibernate bug. The problem was actually more subtle than that. Let us say that I have this scenario:

Post post = session
  .CreateCriteria(typeof(Post))
  .Add(Expression.Eq("Id", 15))
  .SetFetchMode("Status", FetchMode.Join)
  .UniqueResult<Post>();

Console.WriteLine( post.Status.Name );// should not cause lazy loading.

I looked at the result, and looked at the result, and couldn't quite figure it out. Eventually it dawned upon me that the Posts' table had the following data:

Id Content Status
15 Interesting... PUBLISHED

While the PostStatuses table had this data:

Id Name
Published Published
DRAFT Draft

Do you see the problem? While NHibernate has correctly loaded the associated PostStatus entity, it has loaded it with the 'Published key, while the PostStatus entity on the Post was loaded with the 'PUBLISHED' key. Hence, it didn't exists in the current session, and when accessed, would cause a lazy load. Of course, at the DB level it didn't matter because it is set up to be case insensitive, but it sure made a different for comparing key equality on the CLR.

In this case, it was a simple case of entering the wrong value to the PostStatuses table that cause all this issue. As an aside, NHibernate has ways to deal with such cases in legacy databases, but that is something that I would rather fix in the data layer.


Comments

Haacked

Yet another reason I prefer surrogate keys for ids in databases. ;)

Frans Bouma

Same here, string / date based PK fields are evil if you use them for things like descriptions. A customerID as a string... ok, but this example perfectly proofs that an ID should have been used: Your whole Status table is redundant. It looks like a normalized table but the attribute that identifies a status is identical to the name attribute :)

Ayende Rahien

Frans,

It is actually there for a good reason, because:

CUSTOMERISDOFUS key is shown as "Documentation Issue" to the user

Thomas Eyde

OT: Why is the type specified twice, and with different syntax?

First with: CreateCriteria(typeof(Post)),

Then with: UniqueResult()

Ayende Rahien

Because the last is a generic method that saves me a cast, it has no other meaning.

Comment preview

Comments have been closed on this topic.

FUTURE POSTS

  1. The insidious cost of allocations - one day from now
  2. Buffer allocation strategies: A possible solution - 4 days from now
  3. Buffer allocation strategies: Explaining the solution - 5 days from now
  4. Buffer allocation strategies: Bad usage patterns - 6 days from now
  5. The useless text book algorithms - 7 days from now

And 1 more posts are pending...

There are posts all the way to Sep 11, 2015

RECENT SERIES

  1. Find the bug (5):
    20 Apr 2011 - Why do I get a Null Reference Exception?
  2. Production postmortem (10):
    03 Sep 2015 - The industry at large
  3. What is new in RavenDB 3.5 (7):
    12 Aug 2015 - Monitoring support
  4. Career planning (6):
    24 Jul 2015 - The immortal choices aren't
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats