NHibernate Mapping - <component/>
<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:
And this object model:
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:
And then we let NHibernate sort it out and give us our pretty object graph.
Comments
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.
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 :-)
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.
pb,
Take a look at all-delete-orphans.
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.
Dmitry,
This is not for a {component/}, you are looking for {one-to-one/}
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.
Dmitry,
I think so, take a look at the xsd.
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.
How would you map two address components in this example? Would the property name prevent reuse of same component class?
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.
Back on topic...
Does Entity Framework have a feature or concept similiar to this?
Sumod,
You can use more than one component, just use a different property.
for example:
{component name="ShippingAddress"}
{component name="BillingAddress"}
El,
I neither know nor care much...
@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.
Yeah, that worked with a ColumnPrefix on the [Nested], thanks!
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?
Version in a component doesn't really make sense, so I would assume not.
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?
Jose,
Please ask in the mailing list
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.
www.lmgtfy.com/?q=nhibernate+users+mailing+list
Thanks and sorry for the inconvenience. I think you are talking about a explicit nhibernate validator mailing list not the nhibernate group.
Best regards.
Comment preview