Archive for July, 2007

More on NHibernate and ITransactionFactory

2 commentsWritten on July 21st, 2007 by
Categories: NHibernate, Software Development

A while ago i submitted a patch to fix the issue i had with NHibernate ignoring the hibernate.transaction_factory setting. The patch has now been committed to the NHibernate subversion repository. The name of the setting has been changed to hibernate.transaction.factory_class though.

So now you can define which ITransactionFactory you want NHibernate to use in your config file, or from code without using my dirty reflection workaround as this test demonstrates:

    [Test]
    public void SettingsTransactionFactoryReturnsConfiguredTransactionFactory()
    {
      Configuration configuration = new Configuration();
      configuration.Properties[Cfg.Environment.TransactionStrategy] =
        "NHibernate.Test.NHSpecificTest.NH1054.DummyTransactionFactory, "
        + this.GetType().Assembly.FullName;

  ISessionFactory sessionFactory = configuration.BuildSessionFactory();

  Assert.IsInstanceOfType(typeof(DummyTransactionFactory),
    sessionFactory.Settings.TransactionFactory);
}

To avoid any confusion: Cfg.Environment.TransactionStrategy is a public string containing "hibernate.transaction.factory_class"

You will need either NHibernate from trunk to use this, or wait for the 1.2.1 release.

Native ID generation with NHibernate

10 commentsWritten on July 17th, 2007 by
Categories: NHibernate, Software Development

i was looking for a way to define the mapping of an ID field so it would work on both Oracle and SQL Server... In case of Oracle, it would have to use a Sequence that i can define. On Sql Server, it should use an Identity column. Luckily, NHibernate offers just that... the 'native' ID generator uses identity on sql server and a sequence on Oracle.

Unfortunately the 'native' generator is hardly documented in the Nhibernate reference documentation so it wasn't really clear to me which sequence would be used, or how i could define my own. All the documentation says is basically:

For cross-platform development, the native strategy will choose from the identity, sequence and hilo strategies, dependent upon the capabilities of the underlying database.

So how can you define which sequence it should use in case of Oracle? Very simple actually... turns out you just define the sequence name in the same way you would as if you set it to use the 'sequence' generator.

So here's how you do it:

    <id name="Id" column="CustomerId" type="long" unsaved-value="-1"
        access="field.camelcase-underscore">
      <generator class="native" >
        <param name="sequence">sq_customer</param>
      </generator>
    </id>

On Oracle, it will use the sq_customer sequence whereas on SQL Server the sequence parameter will be ignored and it will use the Identity setting of the column that was defined as the ID (in this case, CustomerId's Identity settings)

NHibernate Mapping Examples

43 commentsWritten on July 15th, 2007 by
Categories: NHibernate, Software Development

UPDATE: i've created some new examples which use the latest NHibernate version and demonstrate more features of NHibernate. Read more about it here.

When you're starting out with NHibernate, it's sometimes hard to find good examples. Most examples online are too simple, or are incomplete (just the mappings, but no code for instance). It's always easier if you have some examples that are large enough, but still small enough to be easy to grasp. So i created mappings and classes for the Northwind tables. I figured this could be useful reference material for anyone new to NHibernate so i'm making the whole thing available for everyone. You'll find examples of one-to-many, many-to-one and many-to-many associations in there. I used a couple of different cascade options for the associations, depending on the constraints on the tables. I've also included about 60 unit tests to verify the mappings are working correctly. These tests should also give you a good idea about how NHibernate deals with certain mappings and options.

I did modify the Northwind database here and there... the zip file contains all the sql create scripts. This is what my version looks like:

Northwind Table Diagram

And the class diagram looks like this:

Northwind Class Diagram

I do want to make it clear that this is just an example. I'm not saying that this how you should map your objects and their associations to tables and their relationships. I pretty much provided every possible association in this example, whereas on a real project i'd only create the associations that i actaully need to implement the required functionality. But for the purpose of this example, i thought it would be a good idea to provide as much as possible.

You can download it here

Visual Studio 2008 release date

1 Comment »Written on July 12th, 2007 by
Categories: Software Development

In case you didn't know already, Visual Studio 2008, SQL Server 2008 and Windows Server 2008 will all be released on February 27th, 2008.

More info can be found here

i kinda hoped Visual Studio 2008 would be released sooner (like November 2007 or so) but alas...

Implementing a Value Object

5 commentsWritten on July 8th, 2007 by
Categories: Patterns, Software Development

A Value Object (also known as Immutable Object) is basically an object without a conceptual identity. A Value Object is defined through its inner values, and not an identity like Entity Objects. This means that a Value Object's inner values can not be changed after object creation, hence the term Immutable Object. Should you need to change the inner values of the Value Object, you should actually create a new Value Object.

For some of you, this might seem odd. But you've actually used Value Objects on many occassions already. In .NET, strings are Value Objects. So are DateTime instances. If you create a string, you can't modify its inner value. If you do, a new string is actually created. Same thing with a DateTime. The DateTime class provides methods to add days, hours, seconds, whatever... but those methods never modify the instance's inner value. Instead, they return a new DateTime object because each DateTime instance is immutable.

This also has interesting consequences on object equality. Two Value Objects holding the same data should be considered identical objects, even though they point to different memory locations.

Value Objects are great and can make a lot of things much easier for you. In this post, i'm going to show you how you can easily create a true Value Object while avoiding some common pitfalls.

For this example, i'm going to create an Address class. An Address instance needs to hold some data (street, city, region, postalcode, country, phone number). This data can often be identical between other Entity objects. Maybe I have a Person class which needs to hold an Address. Two people living in the same house would have the same physical address. Both Person instances should then have the same Address too. Husband.Address.Equals(Wife.Address) should return true without having to worry about some unnecessary identity of the Address instances.

This is how our first implementation of the Address class would look like:

  public class Address
  {
    public Address(string street, string city, string region,
      string postalCode, string country, string phoneNumber)
    {
      _street = StringValueOrEmptyString(street);
      _city = StringValueOrEmptyString(city);
      _region = StringValueOrEmptyString(region);
      _postalCode = StringValueOrEmptyString(postalCode);
      _country = StringValueOrEmptyString(country);
      _phoneNumber = StringValueOrEmptyString(phoneNumber);
    }

    private string StringValueOrEmptyString(string value)
    {
      return (value != null ? value : string.Empty);
    }

    private string _street;

    public string Street
    {
      get { return _street; }
    }

    private string _city;

    public string City
    {
      get { return _city; }
    }

    private string _region;

    public string Region
    {
      get { return _region; }
    }

    private string _postalCode;

    public string PostalCode
    {
      get { return _postalCode; }
    }

    private string _country;

    public string Country
    {
      get { return _country; }
    }

    private string _phoneNumber;

    public string PhoneNumber
    {
      get { return _phoneNumber; }
    }
  }
}

So now an Address instance's values can not be changed after object creation. By the way, in case you're wondering why i assign string.Empty instead of allowing null references to my fields: it's because i want to avoid checking for null every time i want to use my fields later on in my code. This is known as the Null Object Pattern.

Now we have to make sure that 2 Address instances holding the same data are actually recognized as equal objects. First, we'll override the Equals method:

    public override bool Equals(object obj)
    {
      Address address = obj as Address;

      if (address != null)
      {
        return
          _street.Equals(address.Street) &amp;&amp;
          _city.Equals(address.City) &amp;&amp;
          _region.Equals(address.Region) &amp;&amp;
          _postalCode.Equals(address.PostalCode) &amp;&amp;
          _country.Equals(address.Country) &amp;&amp;
          _phoneNumber.Equals(address.PhoneNumber);
      }

      return base.Equals(obj);
    }

Thanks to the Null Object Pattern, i don't need null checks when accessing my fields which is great because i really dislike null checks all over the place. Anyway, back to the subject at hand: Equals will return true if the values of the instances are identical.

If you override the Equals method, you really should override the GetHashCode() method as well:

    public override int GetHashCode()
    {
      return _street.GetHashCode() ^
           _city.GetHashCode() ^
           _region.GetHashCode() ^
           _postalCode.GetHashCode() ^
           _country.GetHashCode() ^
           _phoneNumber.GetHashCode();
    }

Ok, our Address instances will behave properly when they are compared with the Equals method. A lot of developers prefer to use the == and != operators though, so we should make sure that these operators also compare the actual values instead of the default reference equality check. For that, we'll simply overload the operators:

    public static bool operator ==(Address address1,
      Address address2)
    {
      if (!object.ReferenceEquals(address1, null) &amp;&amp;
        object.ReferenceEquals(address2, null))
      {
        return false;
      }

      if (object.ReferenceEquals(address1, null) &amp;&amp;
        !object.ReferenceEquals(address2, null))
      {
        return false;
      }

      return address1.Equals(address2);
    }

    public static bool operator !=(Address address1,
      Address address2)
    {
      return !(address1 == address2);
    }

In the == overload, we need to check if the values we've received aren't null. If one of them is null, and the other isn't, then they obviously can't be equal. But how are you going to check if they're null? You can't use address1 == null or adress2 == null because then you'd go straight back into this == overload which would cause a stack overflow. So we use Object.ReferenceEquals() to do the check for us. If neither of the objects is null, we simply return the result of calling the Equals method.

We now have a true Value Object. Its values are immutable, and the instances will behave properly when checked for equality. The following tests all pass:

  [TestFixture]
  public class AddressTests
  {
    private string _defaultStreet = "MyStreet 243";
    private string _defaultCity = "MyCity";
    private string _defaultRegion = "MyRegion";
    private string _defaultPostalCode = "12345";
    private string _defaultCountry = "MyCountry";
    private string _defaultPhoneNumber = "123-4567-89";

    [Test]
    public void TwoInstancesWithSameDataAreEqual()
    {
      Address address1 = CreateTestAddressWithDefaultData();
      Address address2 = CreateTestAddressWithDefaultData();

      Assert.AreEqual(address1, address2);
      Assert.That(address1 == address2);
    }

    [Test]
    public void TwoInstancesWithDifferentDataAreNotEqual()
    {
      Address address1 = CreateTestAddressWithDefaultData();
      Address address2 = new Address(_defaultStreet + "2", _defaultCity, _defaultRegion,
        _defaultPostalCode, _defaultCountry, _defaultPhoneNumber);

      Assert.AreNotEqual(address1, address2);
      Assert.That(address1 != address2);
    }

    [Test]
    public void NullAddressReferenceDoesntCrashWhenUsingEqualityOperator()
    {
      Address address1 = null;
      Address address2 = CreateTestAddressWithDefaultData();

      Assert.That(address1 != address2);
    }

    [Test]
    public void TwoInstancesWithSameDateReturnSameHashCode()
    {
      Address address1 = CreateTestAddressWithDefaultData();
      Address address2 = CreateTestAddressWithDefaultData();

      Assert.AreEqual(address1.GetHashCode(), address2.GetHashCode());
    }

    [Test]
    public void TwoInstancesWithDifferentDataDoNotReturnSameHashCode()
    {
      Address address1 = CreateTestAddressWithDefaultData();
      Address address2 = new Address(_defaultStreet + "2", _defaultCity, _defaultRegion,
        _defaultPostalCode, _defaultCountry, _defaultPhoneNumber);

      Assert.AreNotEqual(address1.GetHashCode(), address2.GetHashCode());
    }

    private Address CreateTestAddressWithDefaultData()
    {
      return new Address(_defaultStreet, _defaultCity, _defaultRegion,
        _defaultPostalCode, _defaultCountry, _defaultPhoneNumber);
    }
  }