views:

21

answers:

0

The docs for NHibernate clearly state that properties (and I assume, by extension, components) with any access modifier can be mapped. However, this is not the behaviour I'm seeing, and I'm wondering if anybody can tell me if this is my mistake or if it is the result of some poorly-documented behaviour in NHibernate.

The component class (some unimportant methods omitted):

public class IPAddressComponent
{
    public virtual byte Octet1 { get; set; }
    public virtual byte Octet2 { get; set; }
    public virtual byte Octet3 { get; set; }
    public virtual byte Octet4 { get; set; }
}

The containing class:

public class Host
{
    public virtual Guid ID { get; set; }
    // snip a bunch of other auto-properties
    // ...
    protected internal virtual IPAddressComponent IPComponent { get; set; }
    public virtual int Port { get; set; }
}

The mapping:

<class name="Host" table="Hosts">
  <id name="ID" column="HostID">
    <generator class="guid"/>
  </id>
  <component name="IPComponent">
    <property name="Octet1" column="Host1"/>
    <property name="Octet2" column="Host2"/>
    <property name="Octet3" column="Host3"/>
    <property name="Octet4" column="Host4"/>
  </component>
  <property name="Port"/>
</class>

So... as is, this code/mapping combo doesn't work properly, the HostComponent is always null when I load an entity. However, if I change the access modifier on that property from protected internal to public, it gets populated fine, which tells me that it's not any obvious problem with the mapping itself. I'm aware of the behaviour wherein NHibernate will null the component if all of the sub-properties are also null, but that does not seem to be related to this issue.

Does NHibernate not supported non-public component properties, or am I doing something wrong here?

P.S. If anyone's curious, I've used this clumsy workaround so I can expose a plain-vanilla immutable IPAddress property in the mapped Host class and convert to/from IPAddressComponent. The underlying database uses 4 byte fields. If there's a better way to do this mapping, I welcome any suggestions; however, I still need to answer this particular question because it could easily come up under other circumstances.