Ayende @ Rahien

It's a girl

NHibernate Mapping -

<component/> is an interesting feature of NHibernate, which map more or less directly into the notion of a Value Type in DDD. This is a way to create an object model with higher granularity than the physical data model.

For example, let us take the following table:

image

And this object model:

image

They are quite different, where the physical data model put all the data in a single table, we want to treat them in our object model as two separate classes. This is where <component/> comes into play:

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

	<id name="Id">
		<generator class="identity"/>
	</id>
	<property name="Name" />
	<component name="Address">
		<property name="Line1"/>
		<property name="Line2"/>
		<property name="City"/>
		<property name="Country"/>
		<property name="ZipCode"/>
	</component>
</class>

This mapping will translate between the physical data model and the object model. And the mapping is complete, so even queries are done in the way you would expect it:

image

And then we let NHibernate sort it out and give us our pretty object graph.

Comments

G
04/08/2009 02:10 PM by
G

Thanks! Been working with NHibernate for many years and have never used this feature (or even noticed it). It may very well come in handy.

JeroenH
04/08/2009 02:18 PM by
JeroenH

As others have pointed out, really useful series. It's a great way of learning about NHibernate in small, digestable, concise chunks.

Thanks for the effort in enlightening us, mere mortals :-)

pb
04/08/2009 04:09 PM by
pb

One thing I've never been able to find an example on is how to have deleted items from an IList be deleted in the DB automatically, similar to how whether or not you add or update an object in an ILIst, calling SaveOrUpdate will do the appropriate thing. I wish there was a SaveOrUpdateOrDelete on the list itself that just peristed the whole list to the DB.

What I do to deal with this now is keep the original list and compare it to the saved list and call Delete on any items that are missing. I could react to row changed events on a grid for example but I like to keep from having to do that in every location and just deal with a single list object, make changes to it (which could include binding it to a grid), then persist it.

Ayende Rahien
04/08/2009 04:17 PM by
Ayende Rahien

pb,

Take a look at all-delete-orphans.

Dmitry
04/08/2009 06:50 PM by
Dmitry

Thanks for the NHibernate topics. As others pointed out, they are really useful.

Is there a way to map a value object when its primary key is different than the linking field? To illustrate my point better. I have a table Person (ID, Name) and a table Address (ID, PersonID, ...). A person can only have 1 address. I could not make 1-to-1 association work because it expects the ID to be the same.

Ayende Rahien
04/08/2009 07:38 PM by
Ayende Rahien

Dmitry,

This is not for a {component/}, you are looking for {one-to-one/}

Dmitry
04/08/2009 09:11 PM by
Dmitry

Sorry for going off-topic but is there a way to have a one-to-one associations when the ID fields in the 2 tables are named differently. I could not find anything in the "NHibernate in Action" book or on Google.

Ayende Rahien
04/08/2009 09:46 PM by
Ayende Rahien

Dmitry,

I think so, take a look at the xsd.

pb
04/09/2009 01:38 AM by
pb

I'm not talking about a parent child relationship, just a simple example of loading a collection of entities and then wanting to do CRUD on them. Delete is a special case and has to be handled differently than saveorupdate.

Sumod
04/09/2009 11:39 AM by
Sumod

How would you map two address components in this example? Would the property name prevent reuse of same component class?

El Guapo
04/09/2009 12:36 PM by
El Guapo

Dmity, your database model is wrong. You said:

"I have a table Person (ID, Name) and a table Address (ID, PersonID, ...). A person can only have 1 address"

Your second statement does not agree with your first statement. You need to fix that, before attempting to model it.

El Guapo
04/09/2009 12:37 PM by
El Guapo

Back on topic...

Does Entity Framework have a feature or concept similiar to this?

Ayende Rahien
04/09/2009 02:54 PM by
Ayende Rahien

Sumod,

You can use more than one component, just use a different property.

for example:

{component name="ShippingAddress"}

{component name="BillingAddress"}

Ayende Rahien
04/09/2009 02:55 PM by
Ayende Rahien

El,

I neither know nor care much...

Dmitry
04/10/2009 12:35 AM by
Dmitry

@El Guapo

It's a legacy database where some one-to-one relations are mapped as many-to-one. I ended up mapping Address as an entity and implemented data constraints in the data access layer.

Sumod
04/10/2009 01:44 PM by
Sumod

Yeah, that worked with a ColumnPrefix on the [Nested], thanks!

Frank Quednau
04/13/2009 06:46 PM by
Frank Quednau

Ayende,

do you know off-hand whether a "technical" field like version or timestamp or user stamps can appear in a "component" section, that way expressing regularly used fields by association, not by inheritance?

Ayende Rahien
04/21/2009 07:31 AM by
Ayende Rahien

Version in a component doesn't really make sense, so I would assume not.

Jose Salvador
05/04/2009 06:45 PM by
Jose Salvador

I have arrived here from a google search I have done looking for a doc about nhibernate validator and value types. I mean:

class Foo : NHibernateEntityClass

{

[NotNullNotEmpty]

public string Prop1;

public Bar bar;

}

struct Bar

{

[NotNullNotEmpty]

public string prop1;

}

With this code (it's only an example) if I validate the foo object the bar class validation at prop1 willl not execute and I can not decorate the bar property at foo class with the valid attribute which only acts over a nhibernate entity types...

Is there any way to get this whithout custom validator which decorates the bar property at foo class?

Can you help me?

Ayende Rahien
05/04/2009 06:51 PM by
Ayende Rahien

Jose,

Please ask in the mailing list

Jose Salvador
05/05/2009 11:47 AM by
Jose Salvador

Of course Ayende but... What is the mailing list you are refering to?

Could you show me the path to subscribe myself to the maling list?

Thanks in advance.

Jose Salvador
05/05/2009 02:33 PM by
Jose Salvador

Thanks and sorry for the inconvenience. I think you are talking about a explicit nhibernate validator mailing list not the nhibernate group.

Best regards.

Comments have been closed on this topic.