Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
ASP.NET MVC BindingHelperExtensions.UpdateFrom with NHibernate loaded objects

An interesting issue was brought up on the S#arp Architecture discussion today (it was actually brought up on the old S#arp forum...but then I couldn't plug the new location! ;).  If you use System.Web.Mvc.BindingHelperExtensions.UpdateFrom to copy fields from a submitted ASP.NET MVC form into an object loaded using NHibernate's Session.Load() method, no data may be copied to the object.

Mark, the person who brought up the issue, noticed in the debugger that the object being updated was actually a proxy using Castle.Core.Interceptor.IInterceptor.  The reason that this is occurring is that, by default, NHibernate lazily loads objects.  For example, assume you load a Customer from the DB using Session.Load(); NHibernate won't take the time to talk to the database and set the object's properties until one of the object's properties or methods are invoked on the myCustomer object.

To make this magic trick work, NHibernate gives you a proxy object that informs NHibernate when it's time to actually hit the database; NHibernate uses the Castle Proxy project to facilitate proxying.  Since UpdateFrom uses reflection to update the object's values, it won't kick off the proxy's "time to talk to the database and load the real object" trigger.

You have three options to work around this limitation of UpdateFrom trying to update the proxy object:

  • Add lazy="false" to the opening class tag within the object's HBM file.  This will ensure that the object is not loaded lazily and will not give you an intermediary proxy.
  • Load the object from the database using NHibernate's Session.Get() method.  This method will never return a proxied object.  (This replaced NHibernate's deprecated Find() method.)
  • Look at one of the properties or invoke a method on the object before your call to UpdateFrom.  This will force NHibernate to replace the proxy with the actual object loaded from the database.  (Albeit, not a very elegant solution.)

The first and second options are the cleanest approaches and, as a nice side-effect, you won't have to add "virtual" before that object's properties and methods if you set lazy="false" in the class declaration.

Related references:

Billy McCafferty


Posted 08-08-2008 5:24 PM by Billy McCafferty
Filed under: ,

[Advertisement]

Comments

Kyle Baley wrote re: ASP.NET MVC BindingHelperExtensions.UpdateFrom with NHibernate loaded objects
on 08-08-2008 10:28 PM

Hmmm...none of those options appeal to me though I'd probably go with the first pending performance tests.

Alternatively, I've been using the Deserialize attribute from MvcContrib successfully so that you can pass an entire object to a controller action as a parameter. Which means I don't ever need to use UpdateFrom. It's always seemed kind of magical to me.

Billy McCafferty wrote re: ASP.NET MVC BindingHelperExtensions.UpdateFrom with NHibernate loaded objects
on 08-08-2008 11:54 PM

I'll have to take a look at the Deserialize attribute...can't say I've used it.  What don't you like about the Session.Get() option?

Christopher Steen wrote Link Listing - August 9, 2008
on 08-10-2008 9:50 AM

Link Listing - August 9, 2008

Christopher Steen wrote Link Listing - August 9, 2008
on 08-10-2008 9:50 AM

WPF Styling the ScrollViewer [Via: Matthias Shapiro ] Any recommendation for WPF Datagrid? [Via: Michael...

Dew Drop - August 10, 2008 | Alvin Ashcraft's Morning Dew wrote Dew Drop - August 10, 2008 | Alvin Ashcraft's Morning Dew
on 08-10-2008 11:36 AM

Pingback from  Dew Drop - August 10, 2008 | Alvin Ashcraft's Morning Dew

Mark wrote re: ASP.NET MVC BindingHelperExtensions.UpdateFrom with NHibernate loaded objects
on 08-10-2008 11:56 AM

Not sure if you're still monitoring the old forum. Here's my reply to the thread:

You're absolutely right, when I set lazy="false", the object is no longer a proxy and the UpdateFrom works fine.

I haven't tried the Get() method yet. That may come in handy as I expect that I may _want_ to lazy load on occasion (e.g. data in tabbed controls), but not always.

The property-peek trick doesn't seem to work. Following in the debugger, I see that referencing a property does call the empty constructor on my POCO object. Does that mean NHibernate is pulling the data? In any case, it's not getting updated by UpdateFrom--perhaps because it is still proxied, even though the data is loaded? I guess I need to install SQL Profiler to follow what is really happening.

ASP.NET MVC Archived Blog Posts, Page 1 wrote ASP.NET MVC Archived Blog Posts, Page 1
on 08-10-2008 5:59 PM

Pingback from  ASP.NET MVC Archived Blog Posts, Page 1

User links about "hibernate" on iLinkShare wrote User links about "hibernate" on iLinkShare
on 01-26-2009 5:33 AM

Pingback from  User links about "hibernate" on iLinkShare

jonson wrote re: ASP.NET MVC BindingHelperExtensions.UpdateFrom with NHibernate loaded objects
on 11-09-2010 2:20 AM

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)