Nhibernate the properties of several components of the same type in a class

advertisements

I have a class LINE which contains two properties of type POINT. I would like POINT to be a component property. If LINE were to contain only 1 POINT, this would be no problem, but since it contains 2 POINTs I would think I needed to distinguish them (so a prefix or suffix can be applied to column names). I tried using the PropertyName attribute of the ComponentProperty tag, but still only one set of X and Y columns is generated inside my LINE table.

For clarity, my goal is to have a LINE table with a Point1_X, Point1_Y, Point2_X and a Point2_Y column.

I use Nhibernate.Mapping.Attributes, below you can see my mapping

[Class]
public class Line : EntityBase
{
  [ComponentProperty(PropertyName = "Point1")]
  public UiPoint Point1 { get; set; }

  [ComponentProperty(PropertyName = "Point2")]
  public UiPoint Point2 { get; set; }

  //omitted the constructor

}

[Component]
public class UiPoint
{
  [Property]
  public double X { get; set; }

  [Property]
  public double Y { get; set; }

  //omitted the constructor
}

In the meanwhile I figured out the following XML mapping wil solve my problem

<class name="Domain.WashProcessLine,Domain">
    <id name="Id" />
    <component name="Point1">
       <property name="X" type="Double" column="Point1_X" />
       <property name="Y" type="Double" column="Point1_Y" />
    </component>
    <component name="Point2">
        <property name="X" type="Double" column="Point2_X" />
        <property name="Y" type="Double" column="Point2_Y" />
    </component>
</class>

found an option on https://www.hibernate.org/hib_docs/nhibernate/html/components.html

the following tagging creates the desired table structure, but does give me a casting exception (from UiPoint to IDictionary) when retreiving the property from the database.

So I'm not entirely there yet :(

[Class]
public class Line : EntityBase
{
    [DynamicComponent(1)]
    [Property(2, Name = "X", Column = "Point1_X", TypeType = typeof(double))]
    [Property(3, Name = "Y", Column = "Point1_Y", TypeType = typeof(double))]
    public UiPoint Point1 { get; set; }

    [DataMember]
    [DynamicComponent(1)]
    [Property(2, Name = "X", Column = "Point2_X", TypeType = typeof(double))]
    [Property(3, Name = "Y", Column = "Point2_Y",TypeType=typeof(double))]
    public UiPoint Point2 { get; set; }
}


After looking at the unit tests for Nhibernate.Mapping.Attributes, and trying a number of different solutions, we found that the cleanest way (unfortunately) to fix the situation provided above, was by injecting some raw xml into our mapping. This means we removed the property attributes in our line class and replaced them with a single entry as shown below

[RawXml(After=typeof(ComponentAttribute), Content = @"<component name=""Point1"">
<property name=""X"" type=""Double"" column=""Point1_X"" />
   <property name=""Y"" type=""Double"" column=""Point1_Y"" />
</component>
<component name=""Point2"">
    <property name=""X"" type=""Double"" column=""Point2_X"" />
    <property name=""Y"" type=""Double"" column=""Point2_Y"" />
</component>")]