Monthly Archives: February 2009

How to (n)hibernate

I love Hibernate. Yes I do. I like the abstraction layer Hibernate creates on top of the database so we deal with objects instead of ugly sql.

I’ve used Hibernate quite a few times and I never had any issues with getting it up and running. Just pop the jar into your /lib directory, create your mapping files and the corresponding pojos, then add the hibernate.cfg.xml to tell Hibernate how to get to your tables, and then you’re all good to go.

nHibernate, however, has been causing me quite a lot of pain. Getting it up and running wasn’t as easy as I thought it should’ve been.

To get started with nHibernate with a table called UserContactInfo, you will need the following:

  1. Download nHibernate and copy all the dlls that are included in the binary into your lib directory, or wherever it is that you dump your dlls. I made the mistake of only including nHibernate.dll and it went on to complain that it was missing log4net.dll and a whole host of other ones that I didn’t think I needed.
  2. A hibernate mapping file, UserContactInfo.hbm.xml. Double check the schema definition nhibernate-mapping.xsd file that was included in your download to make sure that everything matches up, i.e. version, namespace, etc. To enable intellisense for mapping and configuration files, copy the appropriate .xsd files to <VS.NET installation directory>\Common7\Packages\schemas\xml or in my case, I put them in <VS.NET installation directory>\Xml\Schemas
  3. The corresponding pojo, UserContactInfo.cs. You must override the Equals and GetHashCode methods and make all the getters and setters for the fields that you are mapping virtual so nHibernate can manipulate them.

    using System;
    using System.Collections.Generic;
    using System.Text;
    namespace CommKit
    {
    public class UserContactInfo
    {
    private String id;
    private String contactId;
    private Int32 numberOfMessagesReceived;


    public UserContactInfo() { }
    public virtual String Id {
    get { return id; }
    set { id = value; }
    }


    public virtual String ContactId {
    get { return contactId; }
    set { contactId = value; }
    }


    public virtual Int32 NumberOfMessagesReceived {
    get { return numberOfMessagesReceived; }
    set { numberOfMessagesReceived = value; }
    }


    public override bool Equals(object obj) {
    if (obj == null) return false;
    UserContactInfo userContactInfo = (UserContactInfo)obj;
    if (this.Id != userContactInfo.Id || this.ContactId != userContactInfo.ContactId)
    return false;
    return true;
    }


    public override int GetHashCode() { return 1; }
    }
    }
  4. The database table that it maps to
  5. nHibernate configuration settings to tell it how to connect to your database. This can be done with xml in the App.config file or programmatically when you’re setting up your Configuration object, like so:

    configuration.SetProperty("connection.provider", "NHibernate.Connection.DriverConnectionProvider");

    configuration.SetProperty("connection.driver_class", "NHibernate.Driver.MySqlDataDriver");

    configuration.SetProperty("connection.connection_string", "Server=hostname;Database=dbname;User ID=username;Password=password");

    configuration.SetProperty("dialect", "NHibernate.Dialect.MySQLDialect");

  6. Download MySQL Connection/Net for connecting to MySQL from .Net here. You should put the MySql.data.dll in either the GAC (usually C:\windows\assembly) and add the qualifyAssembly element in application configuration file, specifying the full name of the assembly, OR, copy it into your application directory, ie. \bin\Release.
  7. Then you can write code like this:

    Configuration configuration = new Configuration();
    configuration.AddAssembly("CommKit");
    ISessionFactory factory = configuration.BuildSessionFactory();
    ISession session = factory.OpenSession();
    ITransaction transaction = session.BeginTransaction();
    UserContactInfo userContactInfo = new UserContactInfo();
    userContactInfo.Id = "uuid";
    userContactInfo.ContactId = "contactId";
    userContactInfo.NumberOfMessagesReceived = 5;
    session.Save(userContactInfo);
    transaction.Commit();
    session.Close();
  8. Other things to remember, there are a few ways to tell nHibernate where to find your mapping files, one way is to add to the configuration object the name of the assembly where they are located. Like so:
    configuration.AddAssembly("CommKit");All mapping files have to be set as an embedded resource. You can change that in the properties of the file itself.
    mapping file properties

Note: Using nHibernate 2.0.1, .NET framework 2.0, MySQL Connector/Net 5.2.5

Integrate integrate integrate

My first project at ThoughtWorks was with a big medical systems provider. We had a big team of about 50 consultants distributed amongst multiple work streams. Each work stream had their own build and needless to say, it was an integration nightmare. There were about 2 or 3 levels of integration builds and they each had a long feedback cycle and of course, was quite brittle and prone to breakage.

Although those broken integration builds were painful, but I am now thankful that they had them at all in the first place.

Phil and I were recently astounded by the fact that we were getting a null pointer exception in the front-end application and we were frantically trying to figure out what we changed in the last 2 hours that could’ve caused such a problem when we realized that someone had changed some php code in one of the back-end applications and since there were no integration tests or points at all, it took us forever to figure out what was going on. Best part was, the apps were released to a dev-integration environment en route to production with this bug in it and no one knew until we spoke up!

I do wonder how it is possible for anyone to build 2 or more applications that are designed to talk to each other but don’t provide a channel by which they can. Integration points are painful, but the earlier you do it, the better. Gotta remember that…

.NET User Controls

One of the things with creating UI forms is that you tend to repeat yourself a lot because the forms have the same general look and feel but just differ on a button here or a textbox there. Thanks to my friend Mark who suggested I looked into creating user controls instead of abstract form classes, I’m penning this down just in case I forget how to do it again in the future.

Creating and using these controls was actually extremely simple, a big contrast from all my previous .Net experiences.

All you need to do is:

1. Create a folder in your project for the controls. If you’re sharing the controls between multiple applications, create a separate library for them and add the library as a reference in your source project.

User controls in solution explorer

User controls in solution explorer

2. When you build your project, your custom user controls will appear as components in your ToolBox so you can drag and drop them in your forms.

ToolBox

ToolBox

And there you go, you have your own components that you can reuse in multiple forms. My next step is to figure out if it’s possible to modify a control after it has been added to a form without modifying the source code for the original control.

Am I cheating on java?

I’ve been helping a friend with a .Net project as of late. Been running into a few puzzling differences not just in terms of technology, which of course, is expected, but also in terms of convention.

In java, unit tests are a part of the project that you’re on, for example if the source tree is:

projectName/src/main/java

then the tests would be in:

 projectName/src/test/java

But in .Net, what I’ve been told is that the tests is a separate project that’s included in the main solution, that references the source project. Can someone explain the reasoning behind that? Or if there are other ways of structuring the tests?

I’m currently trying to create user controls so that forms that have similar functionality can use those controls instead of duplicating code. A bit of research tells me that MSDN documentation sucks (for the lack of a better word), and that I’d have to create an external user control library project and reference it in order to use those controls. Why can’t those user controls live in the source project? Can someone tell me if this is a convention of if there’s a better way? It’ll also be helpful if I could add user controls to the Toolbox in order to have some drag-and-drop fun.

Many thanks in advance!