1

I have the following scenario: I have a component of an entity, but instead of store it in the same table I need to store in a separate table. The relationship between this two tables is one to one at most (1-0:1). The id of the component table is given by the main table, as value object it doesn't have an identity. Now I wonder how can I map the component to be stored in his own table without add an Id to it in the domain model.

2 Answers 2

4

There are three main ways to map a one-to-one relationship: inheritance, one-to-one, and join. I'm pretty sure that all three of these can be configured to share primary keys instead of having to add an additional primary key column. In this case, join sounds like the best fit, since you wouldn't have to create a separate entity. Ayende's article is the best resource for understanding join.

Example (from Ayende's article, but adding a component to the mix):

<class name="Person"
       table="People">

  <id name="Id">
    <generator class="identity"/>
  </id>
  <property name="Name" />

  <join table="Addresses">
    <key column="PersonId"/>
    <component name="Address"
               class="Address">
      <property name="Line1"/>
      <property name="Line2"/>
      <property name="City"/>
      <property name="Country"/>
      <property name="ZipCode"/>
    </component>
  </join>
</class>

The classes for this would look like:

public class Person
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual Address Address { get; set; }
}

public class Address
{
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public string ZipCode { get; set; }
}

Note that Address does not have an Id property, and it's properties are not virtual. This is because Address is not an entity, it is a component. But join allows it to live in a separate table from Person's other properties.

Sign up to request clarification or add additional context in comments.

3 Comments

I was trying to force the use of a component ayende.com/blog/3937/nhibernate-mapping-component after read the blue book (Evans). According to that, components shouldn't be entities. I guess in Hibernate a table is an entity per definition.
Not true. join allows you to spread an entity across multiple tables. Let me add an example - basically the same as Ayende's example, but showing how you would add a component to the mix.
Exactly what I wanted to achieve. I only had not understood how to combine ´join´ and ´component´ until now. Thanks.
0

If the table with the value object is only referenced by one table you can use the primary key of that table as primary key but don't make any methods to access the field in the value object.

If the table is referenced by more other tables then you have to create an own primary key.

You need a primary key to at least join the tables.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.