AjaxPro + NHibernate = Crash

The Problem

I’m currently using Castle ActiveRecord (which builds on NHibernate) for a web project. One problem I was having was pretty annoying when trying to access NHibernate-generated entities as JavaScript objects via Ajax.NET Professional. ASP.NET would hang for a while and then crash completely with the dreaded “Application Unavailable” error from IIS (or something like that).

With no error messages or stack trace, I immediately blamed the NHibernate proxy objects as the reason why this was happening. On this assumption, I started considering what would be involved to use DTOs instead of the actual domain objects. These would be simpler and hopefully, serializable. After going down that path and getting frustrated by the added effort required to make that solution work, I decided to come back to the AjaxPro serialization issue and see if I could figure out what the problem was.

The Cause

After writing some serialization tests using manually created instances of my domain models (not proxies that were generated from the NHibernate repository), I found that I had the same problem. Great, I thought, my class hierarchy is just too complex for the serializer to handle…

Actually, after considering what is happening in the JSON conversion process, it started to make sense. When using ActiveRecord (or NHibernate) you need bidirectional references with any collections (or else you lose a lot of functionality). So the Post object needs to have a Blog property referencing its parent object (which has a collection of Posts as well). Hence the reason for the crash: an infinite loop.

The Solution

Any circular references in your class relationships need to be excluded from serialization by marking those properties with [AjaxPro.AjaxNonSerializable] (in this case, the Blog property of the Post object). If you are a DDD purist, you may not like the idea of tacking attributes all over your domain model, but I already bit that bullet when going with ActiveRecord over pure NHibernate anyway.

Keep in mind that if you are passing JavaScript proxy objects back to the server for deserialization, you will need to reconnect the parent-child associations or NHibernate won’t be able to save them correctly. It is a little work, but much less than using DTOs with a ton of duplicated properties.

Example:

    using System;
    using System.Collections;

    using Castle.ActiveRecord;

    [ActiveRecord]
    public class Blog : ActiveRecordBase
    {
        ...

        private IList posts = new ArrayList();

        ...
        [HasMany(typeof(Post), Inverse=true)]
        public IList Posts
        {
            get { return posts; }
            set { posts = value; }
        }

The Post class:

    [ActiveRecord]
    public class Post : ActiveRecordBase
    {
        ...

        private Blog blog;

        ...
        [AjaxPro.AjaxNonSerializable]
        [BelongsTo("BlogId")]
        public Blog Blog
        {
            get { return blog; }
            set { blog = value; }
        }

I think that it would be helpful if AjaxPro would check for these kinds of things and throw an Exception instead of just crashing, but the rest of it works quite well so I won’t complain too much there. It would also be nice if you didn’t have to wire up bidirectional associations to make NHibernate work. I suppose we have to work with the tools we are given though…

Advertisements

1 comment so far

  1. […] Serialization Problems with NHibernate Entities Posted June 3, 2007 In my previous post, I mentioned how the bidirectional object references that manage parent-child relationships for a […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: