Mapping NHibernate collections one way

I encountered an issue with an NHibernate mapping today that took me a short while to solve so I thought I’d post here to remind myself in future.

I wanted to map a parent child relationship but only manage the persistence from the parent end. Here’s an example:

Blog -< Post

  public class Blog
  {
        public Blog()
        {
        }

        public virtual int BlogId { get; set; }

        public virtual IList<Post> Posts { get; set; }
   }

Which might have the following mappings:


The problem I was having was that saving the blog entity was causing a SQL exception complaining that BlogId wasn’t a nullable field on the Post table. In the end the fix was easy – remove the not null constraint!

The reason being that nhibernate likes to save the Post records first, then go back and update the foreign key values once it has saved the Blog entity.

ASP.NET MVC3 Razor view engine – some initial observations

Over the last couple of days I’ve started playing around with the razor view engine that comes with ASP.NET MVC 3. The first thing you notice is how much cleaner your markup pages look. It’s a real pleasure to code your markup without having to pollute it with masses of special code nuggets to demarcate your C# code. If you haven’t seen any examples yet check out Scottgu’s intro to Razor.

The error reporting still looks like it could do with a little work though. For example yesterday I put code very similar to this in my view:

@for(int i = 0; i < 5; i++) {
    <p>@i.ToString()</p>
@}

And I got an error message like this:

razor_error

Humm… “No overload for method ‘Write’ takes 0 arguments” – what does that mean? Well the answer is that the @ symbol before the closing curly brace isn’t needed. So the fix was simply to make the following change:

@for(int i = 0; i < 5; i++) {
    <p>@i.ToString()</p>
}

I guess once you’ve used razor for even a short while things like this will become second nature, but it had me stumped for a short time and it’d be nice if the error messages due to view engine parser failures were slightly more helpful in identifiying the exact problem.

Be careful where you get your information

The internet is rife with misinformation.

As a developer you tend to depend heavily on searching for examples of how to solve a particular problem such as code snippets, and patterns and practices. There is very little ground breaking work and it is almost certain that someone has been there, done that, and blogged the solution to your problem already.

Problems arise when you choose the wrong source to trust. For example, today I was trying to figure out how to get ASP.NET not to render a name attribute for the form element as we are starting to target XHTML 1.1 compliance for BeforeYouBuy. A quick google came up with this.

Certainly the answer that is proposed is “a solution”, but it’s certainly not “the solution”. A slight modification to my search turned up this how to on the msdn site.

It’s really down to knowing where to look.

MySql “Nested transactions are not supported” exception

If you are getting an unexpected “Nested transactions are not supported” exception from your MySql database then you may have hit this bug.

I firstly suspected Spring.NET, then the MySql ADO.NET driver. We scratched our heads for a couple of days on this one before I found that bug report.

To make a long story short, simply commenting out the query_cache_size option in the my.ini file solved it. What effect this will have on performance I haven’t determined yet.

IIS gzip compression: the missing link

I’ve been wanting to enable gzip compression for our static content (javascript and css files) for a while but just haven’t been able to get IIS 7 to comply. Apparently static compression is enabled by default in IIS 7 but when inspecting traffic using fiddler I wasn’t seeing my static content compressed.

Solution at last

After several hours of googling and trying various unsuccessful solutions I finally found the answer! Buried in the comments of a post on Rick Strahl’s blog, Imad Jureidini had pointed out the following:

I’ve been running into the same issues. Ultimately, the solution was to change the following config setting:

<serverruntime frequenthitthreshold=”1″>

The default value here is “2”, which means that even static content does not get compressed if it isn’t requested twice within a 10 seconds period (frequentHitTimePeriod). Switching to “1” means that the file gets compressed right away.

Hopefully this will fix your problems too 🙂

– Imad

To confirm that this was in fact the problem I was experiencing I did a control refresh of my website several times in very quick succession. Sure enough the css and javascript files suddenly started coming through compressed.

I then used the following command to change the setting in my servers config:

%windir%system32inetsrvappcmd.exe set config
-section:system.webServer/serverRuntime -frequentHitThreshold:1

After restarting IIS I tried a control refresh of the website again. As expected the css and javascript files were delivered compressed on the first request.

Why?

This begs the question – why would Microsoft do such a thing? Surely the point of compression of static resources is to reduce delivery time to the browser. Why should my users care if anyone else has recently requested the particular resource they are interested in? They aren’t and shouldn’t be. These static resources should be compressed first, time everytime. (The only exception to this would be where compression is straining the servers ability to serve content).

Where is the documentation?

I’ve got to say my experiences with IIS 7 to date have been one frustration after the next. Microsoft appears to have put a lot of work into this product and at first glance a lot of the new features look to offer real value. What I don’t understand is why there is so little documentation on this new product. So much has changed from IIS 6 there really needs to be a comprehensive set of documentation available somewhere – if it does exist I have yet to find it…

RowUpdating event and UpdateRow method of a GridView not firing

We struck a bit of an odd problem today. We had an older ASP.NET 2.0 website we were migrating to ASP.NET 3.5 and one of the pages has a GridView on it. As we use Spring.NET and NHibernated Microsofts new objectdatasource approach for binding the GridView won’t fly so we were using old school databinding. This meant we needed to be able to handle the RowUpdating event in order to persist our changes. The problem was that the RowUpdating event just wasn’t firing.

Eventually we tracked it down to a weird interaction between Spring.NET and the GridView where if we wrapped the GridView in a spring:panel and suppressed dependency injection the event started firing. Of course the new and old values that are supposed to be available in that event handler were still null…

There is obviously a bug with the databinding in the GridView somewhere and it seems Microsoft is aware of the issue, however I wouldn’t hold my breath for a fix to be forthcoming.

Personally I think the new objectdatasource model has some serious drawbacks and the fact that Microsoft haven’t made the effort to ensure that custom databinding still works is a real shame to say the very least!

NHibernate onFlushDirty has null previousState

The problem

We use an Entity interceptor to create audit records when we update most tables. We also do a lot of our data access through .NET remoting. This means that we open a session to load the object, the object is detached, serialized, modified, then reattached to the session when we want to persist the changes.

We noticed that in the cases where we are updating detached objects, although the update was being applied correctly there were no audit records appearing in the database. On investigation we realised that the previousState parameter passed into the onFlushDirty method of our interceptor was null.

Why

In the Save method of our data access class we were using the SaveOrUpdate method of the NHibernate session to persist the changes. Section 10.7 of the documentation states:

saveOrUpdate() does the following:

  • if the object is already persistent in this session, do nothing
  • if another object associated with the session has the same identifier, throw
    an exception
  • if the object has no identifier property, save() it
  • if the object’s identifier has the value assigned to a newly instantiated
    object, save() it
  • if the object is versioned (by a or ), and
    the version property value is the same value assigned to a newly instantiated
    object, save() it otherwise update() the object

and merge() is very different:

  • if there is a persistent instance with the same identifier currently
    associated with the session, copy the state of the given object onto the
    persistent instance
  • if there is no persistent instance currently associated with the session,
    try to load it from the database, or create a new persistent instance
  • the persistent instance is returned
  • the given instance does not become associated with the session, it remains
    detached

As our detached objects had an Id and version when we called SaveOrUpdate() they were being updated, and seeing as all update() does is reattach an object to the session, the session had no record of the changes that had been made to that object since it was loaded.

The solution

The solution was to use the merge() method (new in NHibernate 2.0). Merge() checks the first level cache to see if an object with the given identifier has previously been loaded. If so it loads that object out of the first level cache and updates it’s properties using the detached object. This means that the session is now able to track the changes made to the object so that when the flush occurs the previousState is no longer null.

MooTools ASP.NET Webservice Ajax calls.

I had some trouble trying to find an example of how to call an ASP.NET webservice from MooTools. I eventually pieced the bits together from a couple of forum posts and thought I’d post an example here in case anyone else was having the same problems.

If I have an ASP.NET webservice that has a GetById method that takes a single int parameter and returns an object I can call it with the following code:

function doAjaxWebServiceRequest (id) {
var completeDelegate = Function.createDelegate(this, this.callback);
var failureDelegate = Function.createDelegate(this, this.error);
var request = new Request.JSON({url: ‘http://hostname/MyWebService.asmx/GetById&#8217;,
onComplete: completeDelegate,
onFailure: failureDelegate,
urlEncoded: false,
headers: {“Content-type”: “application/json”}
});
request.send(JSON.encode({‘id’: id}));
},

The returned object will be in JSON format. The lines where I create my callback delegates using the Function.createDelegate method allow me to set the scope of ‘this’ in my call backs to be the object I making the request from.

Hope that helps someone out!

Mootools differences in IE and Firefox

We’re using the MooTools scripting framework on our site and today I discovered a strange difference between Firefox and IE. I was creating an element and injecting it into the DOM and then trying to change its CSS class and styles.

addClass and setStyle
MooTools provides methods on it’s Element class that allow you to manipulate the CSS styling of an element. You can do things like:

// Add a css class to the element with the id foo
$(‘foo’).addClass(‘fooStyle’);

// Set the width of the foo element
$(‘foo’).setStyle(‘width’, ‘100px’);

Unfortunately when viewing an ASP.NET page in IE that includes a script that uses these functions you get a script error saying that the “Object doesn’t support this property or method”

At first I thought the solution was to go back to basics:

// Add a css class to the element with the id foo
$(‘foo’).className = ‘fooStyle’;

// Set the width of the foo element
$(‘foo’).style.width = ‘100px’;

However I then realised that I was trying to call the MooTools Element methods on a vanilla element object rather than a MooTools one. The second line below solved the problems in IE and meant I could go back to the first way of applying the styling.

var myelement = document.createElement(“a”);
myelement = $(myelement);

IE vs Firefox
In retrospect it seems strange that this worked in Firefox, I guess Firefox must be able to do some sort of implicit conversion to a MooTools element in order to resolve the method call.

MooTools seems really great, it’s lightweight and easy to use. The learning curve seems much lower than some of the other more complicated offering available.

The only reservation I have at this point is that from what I’ve read on the forums it doesn’t play nicely with any other scripting framework due to it’s lack of namespaces and the maintainers seem quite hostile to anyone who suggests that would be a good thing.