If you use NHibernate heavily then you have a lot to gain from NHProfiler. It is a great tool for identifying problems with how you use NHibernate and how you access and update data. But I think its greatest strength is as a learning tool, as it is makes it easy to understand how NHibernate works and what the consequences of each mapping setup are.

Ok, this post is not just going to be free advertising for Ayende. A nice feature in NHProfiler is that it will show you the context of the data access. For web apps it will show the URL that triggered the data access, for WCF apps it will show the WCF service and operation name.

Example:
image

Here you see that ContractService and operation GetContractStatuses was called and generated one database call. This context is very nice to have when profiling and tuning your application. However in the current project that I am working on we have moved from classic WCF with services and operations to a generic WCF command & query service with just two operations  (SendCommand & SendQuery). This makes the context not so useful anymore.

image

Sorry for the censored image, it hides the project name. Anyway here the WCF service and operation name is not helping much as we do not se what command or query was issued. Fortunately NHProfiler offers a way to programmatically set the context. In order to set the context for this generic command & query service I implemented a ParameterInspector (a WCF extensibility point) in which I set the NHProfiler context.

Here is the code:

public class NHProfMessageInspector : IParameterInspector
{
        public object BeforeCall(string operationName, object[] inputs)
        {
                
                var typeName = inputs[0].GetType().Name;
                var commandOrQuery = "";
                
                if (typeName.EndsWith("Query"))
                {
                        commandOrQuery = "Query";
                        typeName = typeName.Substring(0, typeName.Length - 5);
                }
                if (typeName.EndsWith("Command"))
                {
                        commandOrQuery = "Command";
                        typeName = typeName.Substring(0, typeName.Length - 7);
                }

                var contextString = string.Format("{0} : {1}", commandOrQuery, typeName.ToSentenceStyle());
                SetContext(contextString);

                return null;
        }

        public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
        {
                SetContext(null);
        }

        private void SetContext(string value)
        {
                Assembly profilerAsm = null;

                try
                {
                        profilerAsm = Assembly.Load("HibernatingRhinos.Profiler.Appender");
                }
                catch (Exception) { return; }

                if (profilerAsm == null)
                        return;

                var profilerIntegration = profilerAsm.GetType("HibernatingRhinos.Profiler.Appender.ProfilerIntegration");
                if (profilerIntegration == null)
                        return;

                var currentContext = profilerIntegration.GetProperty("CurrentSessionContext");

                currentContext.SetValue(null, value, null);
        }
}

The BeforeCall method checks the first input type and creates a nice context string based on the type name. The SetContext method does the integration with NHProfiler. This is done through some reflection (in order to not have a strong reference to HibernatingRhinos.Profiler.Appender.dll and be version independent).

The result:
image

Now the context is much more useful! The same approach should be interesting for other people who also use a generic WCF interface or for example NServiceBus. Another option is to set the NHProfiler context in an integration test base class. This could be useful for example if you have a suite of repository tests and you want the text fixture name to appear as the context in NHProfiler.

imageA couple of hours ago I finished a presentation about NHiberante at the Developer Summit 2010 conference being held here in Stockholm.

I have worked with NHibernate in many projects, some greenfield projects but mostly replacing an existing data layer. I have introduced it to many teams. In those teams I have always been the NHibernate guy. The person that people turn to when faced with some NHibernate related problem. So when I started to prepare for this presentation I asked myself what is it that is causing these problems, what is it that people are missing in there understanding?

So the focus of the talk centered around these areas:

Identity Map (L1 Cache)
Understanding how the identity map is an integral part of NHibernate is very important. If you are not aware that you share instances for entities with the same id you can run into some strange bugs and side effects. The identity map is probably one of the main causes of problems when replacing an old DAL layer (that do not use an identity map) with an ORM.

Unit Of Work
Of course it is important to know how the Unit Of Work in NHibernate works, it’s relation to Flush and Transaction (FlushMode Commit).

Session Managementimage
Important to use the session correctly (i.e. do not open and close it in the data layer).   

Cascading
Understanding cascading can be tricky, especially how correctly to use cascade=”none” and how that works in relation to transient instances (it doesn’t). It is important to understand that NHibernate persists all changes to modified entities that are associated with an open session, no matter if you set cascade to none. 

Attached & Detached
It is very important to understand what it means that an instance is attached/associated with an open session. In the talk I show the result when you try to persist a modified detached instance. I also show how you can solve that issue by associating the detached instance with an open session (before the modification) by calling session.Lock and how you can as your last option use session.Merge to update modified detached instances.

Lazy Loading & Proxy Objects
In the talk I show how NHibernate’s lazy loading works via proxy objects and what issues you might run into. For example trying to check the concrete type in an inheritance chain won’t work as the type will always be the proxy object.

ID Generation & unsaved-valueimage
It is important to understand how NHibernate determines if an instance is transient or not and how that plays into id generation. If you need to use assigned id you can still let NHibernate know if an instance is transient or not by using a version column.

Concurrency
I ended the talk by showing how to handle concurrency (by using a version column).

 

If all NHiberante users have a good grasp of the above areas I think they would experience a lot less bugs and head aches. So for those that attended the talk I hope they will not be making the same mistakes I have made and have seen others make. 

Here is a link to download the powerpoint slides

Those who read the tile of this post should have figured out that this post is not about programming but is an account of an interesting trip I recently came home from. An amazing trip that took me through Kazakhstan, Kyrgyzstan and Uzbekistan. So if you want to know something about Central Asia please continue to read otherwise skip this post.

The trip focused on the history of this region and it’s people. The region is famous for it’s huge steps, incredible mountains and vistas and it’s rich history and art. It contains enchanting cities like Samarkand and Bukhara. Cities that has existed for millennia as important centers of commerce along the silk road.   

The most interesting part of the trip, and the one I wish to retell in more detail is the event that happened in Bishkek (the capital of Kyrgyzstan). We were invited to the parliament by Edil Baisalov, the current chief of staff of the interim government. For those who haven’t followed the news of this region: There was recently (April 6-15) and uprising in Kyrgyzstan where the then president Kurmanbek Bakiyev and his government was removed and replaced by an interim government. One of the many reasons for the uprising was the shutting down of news outlets that were critical of him and his son.

Why would a central figure from the new interim government invite a group of Swedish tourists?  Edil Baisalov was recently a political refuge fleeing Kyrgyzstan in late 2007. He feared imprisonment or assassination from president Bakiyev. He ended up in Sweden. He was very moved by the way Sweden accepted him and his family, how they were provided with an apartment, free language education and counsel. Now, when a group of Swedish tourists, in this time of political crisis, dared to enter the partially closed border and go forward with their trip through Kyrgyzstan, I think he felt obliged to say something.  I am not sure exactly what his motives were. 

The meeting took place on the 5th of May. The group of forty Swedish tourists was led into a big round table room in the parliament building. After a few minutes Edil Baisalov entered, greeting us in Swedish. He switched to English and continued to talk a little bit about himself, his history with activism for human rights and against corruption. Baisalov was a very open critic of the Bakiyev government, criticism that finally led to him having to flee from Kyrgyzstan. One thing that struck everyone from the beginning of the meeting was how very candid and honest this person sounded - this was no ordinary politician. And reading his profile in Wikipedia shows that this is a longtime activist, who is not used to have power and to be careful about what he says. 

_DSC0301And what Baisalov said was very interesting. He was asked: "How are you going to fix it?" referring to the current state of political crisis.

Baisalov said that the main focus is to organize free and fair elections this fall. They are working on changing the constitution in the direction to become a parliamentary republic, increase freedom of speech and improve the election and voting system.

Another focus he mentioned was to improve the situation for women - from education and job opportunity standpoint. He said that Kyrgyzstan has a population of very well educated women, almost more so than men (for example his mother was a doctor and his father a driver). This he said was a legacy from the Soviet times, when the situation between men and women were more equal (compared to today) and where everyone could get an education. He said that the situation for women has deteriorated and is regressing. This trend he wishes to reverse.

He was asked about relations to Russia and the States.

He answered by saying that Russia quickly accepted the interim government. Mainly (he thought) because Bakiyev had cheated Russia by accepting money from Russia to build a power station, but in return for the money Bakiyev should have barred the States the use of the military airport. He did not comply with this demand. This and other similar situations caused Russia to be offended by Bakiyev. This Baisalov thought was one of the reasons behind Russia’s quick approval of the uprising and ousting of Bakiyev.

With regards to the interim government and its relations to The States: He said that they were finding evidence that the States had bribed military and government officials in order to use the airport in Bishkek. "They fight for democracy in Afghanistan while they sacrifice democracy in Kyrgyzstan".  But he said that they (the interim government) will continue to allow the USA to use the airport and it is for the next elected government to decide on this issue.

He also mentioned that Bakiyev's son, known as the ‘prince’ and was touted as his almost certain successor, was visiting _DSC0308Washington a few months back (maybe to talk the military air base). He was accepted as an official of the government even though he was dismissing the democratic process in Kyrgyzstan. Baisalov mentioned these two stories as possible causes for the apprehension of the attitude of the USA towards the new interim government knowing that they supported and even encouraged the corruption within Bakiyev’s government.

He was also asked to talk about what happened during the uprising that led to the ousting of president Bakiyev. He mentioned a former minister of defense who was very popular among the military and critical of Bakiyev. This person was sentenced to prison for 8 years on trivial charges. During the uprising this person was freed and due to his popularity within the military helped secure their support for the demonstrators. Baisalov also mentioned that they recently had discovered 8 million dollar in a bank security box belonging to the previous defense minister (the one who had replaced the one who was sent to prison).

When Baisalov continued to describe what happened during the days of the uprising he choked, after multiple tries. It was clear that the pain from losing close friends just weeks earlier was too much and to soon. 88 people were killed and 500 hospitalized during the demonstrations.

He added his view on secularism, about the long term goal of reaching something like the social democracy in Scandinavia, about ways to make politics more about ideology and issues than about clans and individuals. Baisalov expressed following important opinion: “Even if we’ll lose the election we’ll win. The purpose is to gain a democratic system”. Much more was said but I cannot remember more specifics.

The whole group left the event in a strange mood. What we just had heard was so very unexpected and unique. It is not often you get the possibility to visit a parliament after an uprising and talk to one of the leading opposition leaders and activists in the country, or listen to a politician that felt so honest and human. Everyone walked out from that meeting with a great hope that Kyrgyzstan might be the first real democracy in Central Asia, if the elections and everything pan out. But because of Baisalov’s very personal account everyone also walked away with a personal connection to Kyrgyzstan and its fight for democracy and human rights. Personally I and I think many others in the group will be following the events very closely from now on.

In order to thank Baisalov for taking the time to talk to us, I would like to recommend to everyone to visit Kyrgyzstan. It is an amazingly beautiful country with a friendly and fun people.

North Kyrgyzstan, near Issyk-kul lake:
_DSC0155

_DSC0136

A very young goat herder that came and said hello:
_DSC0189

View from hotel I stayed at in central Bishkek:
_DSC0255

Registan in Samarkand:
_DSC0382

The cities were not what I expected, the cities Almaty, Bishkek and Tashkent where much more modern, clean and organized than I expected. But most of all they were green and beautiful, with parks everywhere and trees planted along every street. Still these are very poor countries, with vast differences between rich and poor and low expected living age. For example GDP per capita in Kyrgyzstan is 934$ compared to 52 000$ in Sweden (source Wolfram alpha). But I encourage everyone who wants to experience something different to travel to Central Asia. I will definitely be returning, maybe a hiking trip in Kyrgyzstan! 

I have blogged before about my visual studio color settings.

I just found a new site called Studiostyles that allows you to create visual studio color schemes via an intuitive interface (using javascript). You can then submit the scheme and have other people vote on it. I just submitted my theme: http://studiostyles.info/schemes/coding-instinct-theme  please vote it up!  You cannot select font type in the Studiostyles scheme creator, that is why it is displayed using courier new instead of the better Consolas font. 

Screenshots:

image

image

I would not recommend that you use the NHibernate "bag" mapping option for a many-to-many association, for example:

image

Never mind the strange domain, it is for a upcoming NHibernate presentation and I was too bored with the normal Order > OrderLines example domains.

The reason why using a bag for many-to-many is not recommended is because of the poor update behavior you get. If you were to load an entity (RebelEncounter in this case) that has a ShipsLost many-to-many association and just add another StarDestroyer to the ShipsLost collection like this:

image

This would be issued to the database:

many_to_many_using_bag

As you can see all the existing ships where deleted and then reinserted (along with the single new one you added). You can probably guess that this is far from ideal from a performance stand point. However it is easy to fix. First we have to change the mapping from bag to set:

image

NHibernate will use the HashedSet type from the Iese.Collection framework as the collection type when using the set mapping, that means that the type for the property can no longer be IList<StarDestroyer> since HashedSet does not implement that interface, however it does implement ICollection<T>. So we can change the code to something like this:

image

With this change NHibernate will now only insert the newly added entity:

image

Series Index

  • Part 1: Reusable controller actions & model inheritance
  • Part 2: Custom meta data provider (coming soon)

One of the great new features in ASP.NET MVC 2 is the template system. It is very similar to the template form helper system introduced in MvcContrib for MVC V1. For more information on the MVC template system read Brad Wilsons excellent series

This template system allows you to create convention based views and forms. The scenario that I have been working with the last couple of days is forms for reports. These forms are all very similar, that is they are all built around a couple of report filters/parameters built using dropdowns, checkboxes and datetime pickers.

My idea was that each report would only consist of a new report model and the most of the views, and controller actions could be reused.

Example:

public class ReportController : Controller
{
    public ViewResult ViewRequestForm()
    {
        return View("ViewForm", new RequestReportForm());
    }

    public ViewResult ViewOrderForm()
    {
        return View("ViewForm", new OrderReportForm());
    }

    [HttpPost]
    public ActionResult ViewReport(ReportForm form)
    {
        return View(form.GetReportParameters());
    }
}
The idea is to be able to reuse the same root view and the same action for all forms. The root view is only going look something like this:
<% Html.BeginForm("ViewReport", "Report"); %>

    <%=Html.EditorFor(x => x)  %>
    <input type="submit" value="submit" />

<% Html.EndForm(); %>

The EditorFor helper is going to start the MVC template engine. This template engine is first going to try to find a matching editor template for the report form model, since no specific template exists it is going to fallback to the default template for object, this template loops through all properties defined on the model and applies an editor for each property.

This is how the RequestReportForm and OrderReportForm model looks like:

public class RequestReportForm : ReportForm
{
    [DisplayName("Include canceled requests")]
    public bool IncludeCanceledRequests { get; set; }

    [DisplayName("Some parameter")]
    public string SomeParameter { get; set; }
    
    public override string GetReportParameters()
    {
        return "RequestFilter=" + IncludeCanceledRequests;
    }
}

public class OrderReportForm : ReportForm
{
    [DisplayName("Group by status")]
    public bool GroupByStatus { get; set; }

    [DisplayName("Some other paramater")]
    public string SomeOrderParameter { get; set; }

    public override string GetReportParameters()
    {
        return "something";
    }
}   

With the default templates built into MVC these models will be rendered like this:

RequestReportForm:

image

OrderReportForm:

image

If we would like to override these templates all we have to do is create our own partial view and name it string.ascx or bool.ascx and place it in a view folder named EditorTemplates, hopefully more on that in a later part in this blog series.

So sharing the same view for both of these report models seems to be very easy with the template system built into MVC 2 but how do we use the same controller action? We want to use the the controller action ViewReport that takes the base type ReportForm as a parameter. The standard DefaultModelBinder will not know which concrete class to bind to. The solution to this problem should be to create a custom model binder that will figure out which concrete form model to instantiate based on some field coming in the post data from the browser.

Example:
public class ReportFormModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var reportFormTypeName = bindingContext.ValueProvider.GetValue("ReportFormTypeName");

        var reportFormType = Type.GetType("MvcApplication1.Models.ReportForms." + reportFormTypeName.AttemptedValue);

        var model = bindingContext.ModelMetadata.Model;
        
        bindingContext.ModelMetadata = new ModelMetadata(ModelMetadataProviders.Current, 
                bindingContext.ModelMetadata.ContainerType,
                () => model, reportFormType, bindingContext.ModelMetadata.PropertyName);
        
        return base.BindModel(controllerContext, bindingContext);
    }
}

This custom model binder looks for a form data field "ReportFormTypeName". With this name it is possible to get the .NET Type (based on some namespace convention) and thereby create a new ModelMetadata object, now we can call the base implementation. All we need to do now is to add this ReportFormTypeName field as a hidden field to our form. Lets add it to the base class ReportForm, like this:

public abstract class ReportForm
{
    [HiddenInput(DisplayValue = false)]
    public string ReportFormTypeName
    {
        get { return this.GetType().Name; }
    }

    public abstract string GetReportParameters();

}

This is actually all we have to do to get the MVC template system to generate a hidden field named ReportFormTypeName that will contain the name of the concrete Type. Since both RequestReportForm and OrderReportForm inherit from ReportForm and since the default template for object will loop through all properties (including inherited properties) the hidden field will be included for all report forms.

So what have we accomplished? We can generate different report forms by only creating a new form model, the view rendering is shared and the controller action to generate the report is also shared. The controller action that handles the viewing of the report is in my case only responsible for concatenating all report parameters into a querystring to then pass to the report system, since this is so generic it can be handled in the same controller action for all report forms. I hope some of you understand what I am trying to show here, and I also hope to expand on the ideas in this post in later posts. Specifically how to make the report parameters more rich and how to control and override the layout using custom editor templates and custom metadata.

kick it on DotNetKicks.com

One of NHiberantes features that I haven’t seen mentioned in the documentation or in blogs concerns the the two methods on ISession SaveOrUpdateCopy and Merge.

Lets say we have an backend (i.e. application server) that has an operation called UpdateOrder.

image

The UpdateOrder message contains a complete order. The normal scenario here is that the backend translate the order contained in the message to a domain model that is then persisted to the database via NHibernate. The problem with an update scenario like this is that the order that is coming in from the client could have missing order lines. If you use the normal ISession SaveOrUpdate method the order line that was removed on the client and therefore missing in the UpdateOrder message will not be deleted in the database.

Why won’t the missing order line be deleted from the db? Well consider this normal update scenario:

image

Here the order line is removed on the instance that is already attached to an open NHiberante session. In this case SaveOrUpdate will work perfectly because NHiberante can track the removal of the order line.

Consider this case (that represents the client –> backend scenario I mentioned above)

image

Here we try to save a detached instance which means that NHibernate’s dirty tracking and tracking of collection removals will not work.

How do you solve this problem? One approach is to fetch the order from the db and do a manual merge of the changes.  The current system that I am working on has a data access layer that is using LinqToSql and there are many, many update scenarios as described above. The amount of code to manually merge and figure out what has happened with all relations (added / removed order lines for example) is quite substantial.

For the last month we have been bit by bit migrating the data access layer to NHibernate. First I thought that this issue of updating detached objects would be a problem that we still needed to solve manually but then I discovered SaveOrUpdateCopy and Merge. These two functions does exactly what the old DAL did manually, that is before the update it fetches the persisted object from the db and then merges all changes from the detached instance into the persisted instance automatically, including orphaned child deletions!

Ex:

image

In the above code I modify an order line and remove another. Both operations are on a detached object. Then using SaveOrUpdateCopy we get this:

image

NHibernate fetches the order (in one statement by joining in the order lines), then performs the merge, figures out that one order line is updated and one is removed and issues the correct database calls. Is it just me but isn’t this great??? This will literally save thousands of lines of code! 

The ISession.Merge function basically does the same (from what I can tell). I am not sure really what separates them, except that there is cascade option named “merge” that you can set on relations to control how cascades should be propagated during merge operations.

Here is the API doc for Merge:

Copy the state of the given object onto the persistent object with the same
identifier. If there is no persistent instance currently associated with
the session, it will be loaded. Return the persistent instance. If the
given instance is unsaved, save a copy of and return it as a newly persistent
instance. The given instance does not become associated with the session.
This operation cascades to associated instances if the association is mapped
with cascade="merge". The semantics of this method are defined by JSR-220.

I think SaveOrUpdateCopy is something that has exited in NHiberante for all time and Merge is something added in 2.1 (clearly something ported from the hibernate). Anyway I am very glad that NHibernate has this ability because writing and handling the merge operation manually is very boring code to write!