views:

955

answers:

2

I have a person entity containing an Address as a value object:

public Person()
{
    WithTable("Person");
    Id(x => x.Id);
    Component<Address>(x => x.Address, a =>
    {
     a.Map(x => x.Address1);
     a.Map(x => x.Address2);
     a.Map(x => x.Address3);
     a.Map(x => x.Town);
     a.Map(x => x.Postcode);
    });
}

It states in the NHibernate docs that if all the properties of a value object (Address1, Address2 etc) are null, the entire component will be mapped as null (i.e. Person.Address will be null). This is giving me problems in cases where all address fields are null because in my pages where I might have (I'm doing ASP MVC):

<%= Html.TextBoxFor((x => x.Address.Address1))%>

This breaks with a null reference exception. So I'm looking for a clean way to set Address as a new Address() object rather than null if all the fields are empty when I load a Person from the database without doing it manually. I've discounted the following ideas:

Doing null checking in my view (yuk, horrible)

Making database fields not-nullable (I'm dealing with a legacy database)

Anyone any ideas?

+2  A: 

I don't have any definitive answers creating a method/property accessor that isn't mapped, and that returns a default/null-object if the actual address is null.

public Address GetAddressOrDefault()
{
  return Address ?? new NullAddress();
}

Or similar to the first, create a wrapper for your Address that you use in the view.

public class AddressViewData
{
  private Address address;

  public AddressViewData(Address address)
  {
    this.address = address ?? new NullAddress();
  }

  // expose all address properties as pass-throughs
  public string Street
  {
    get { return address.Street; }
  }
}
James Gregory
Becomes pretty ugly as soon as you actually need to edit address in the UI, not just show it, huh?
alex
Yep, got a better suggestion?
James Gregory
Great ideas, thanks! Modifying the actual mapped Address property accessor to allow get and set as usual, but using your null check in the get "Address ?? new Address();" works. I can now load and edit addresses even if they are null, without modifying my view, and hibernate does not get confused.
James Allen
+1  A: 

Thanks to James' ideas (see his answer and comments) I have modified the Address property of my Person entity from:

public virtual string Address { get; set; }

to:

private Address _address;
public virtual Address Address
{
    get { return _address ?? new Address(); }
    set { _address = value; }
}

This has solved my problem, it works, and it seems to work with NHibernate. Yey!

James Allen