NHibernate Mapping - <join/>
We have previously explored the one-to-one mapping, which let you create 1:1 association in the database, but there is actually another way to map several tables to an object model. We aren’t constrained by the database model, and we can merge several tables into a single entity.
We do that using the <join/> element:
<join table="tablename" (1) schema="owner" (2) catalog="catalog" (3) fetch="join|select" (4) inverse="true|false" (5) optional="true|false"> (6) <key ... /> <property ... /> ... </join>
Let us explore this a bit, assuming the we have the following database model:"
And what we want is to map this to the following object model:
We can do this will the following mapping:
<class name="Person" table="People"> <id name="Id"> <generator class="identity"/> </id> <property name="Name" /> <join table="Addresses"> <key column="PersonId"/> <property name="Line1"/> <property name="Line2"/> <property name="City"/> <property name="Country"/> <property name="ZipCode"/> </join> </class>
And getting a Person will now result in the following SQL:
NHibernate will now take care of mapping everything to its place, and making sure that everything works just right.
By now you should be able to figure out what fetch means, and inverse should also be familiar. Optional is interesting, what is basically says is that we should always use an outer join to get the values from the Addresses table and if all the mapped properties are null, it wouldn’t create a new row in the Addresses table.
On the face of it, it looks like a nice way to merge tables together, but that isn’t actually the primary reason for this feature. You can use it for that, for sure, but that is mostly useful in legacy databases. In most cases, your object model should be more granular than the database model, not the other way around.
The really interesting part about this feature is that it allows us to mix & match inheritance strategies. It let us create a table per hierarchy that store all the extra fields on another table, for example. That significantly reduce the disadvantage of using a table per hierarchy or table per subclass, since we can tell very easily what is the type of the class that we are using, and act appropriately.
Comments
It let us create a =table per hierarchy= that store all the extra fields on another table, for example. That significantly reduce the disadvantage of using a =table per hierarchy= or table per subclass...
There's a typo.
Beside this, the post series is awesome :).
The mix & match inheritance strategy you mentioned, is it something like this?
knol.google.com/.../11#8(2E)1(2E)3(2E)(C2)(A0)Table_per_subclass(2C)_using_a_discriminator
Thx
PS: I'm learning a lot from this article series. Thx for spreading the knowledge.
Evgeny,
I don't see the typo
Jan,
Yes, that is what I meant.
Great series of posts.
In the post about {dynamic-component/} i've asked about the way to store key-value pair in detail-table. ayende.com/.../...pping-ltdynamic-componentgt.aspx
I'd like to solve inhertance problem using this key-value princniple. see picture: tweakers.net/.../full.jpg
I want that NHibernate dynamically creates subclasses' attributes using detail-table with key-value pair, where key is the name of the attribute and the value is the value.
Is it possible with NHibernate?
I prefer this solution over the standard ones (like table-per-subclas or table-per-concrete-class), because i have more than 80 subclasses with three hierarchical levels and all with their specific attributes.
Thanks in advance
tolly,
Please follow this up in the mailing list
Thanks, Ayende :) Hopely, I'll find the way.
It's a greate blog, i've learnt a lot of new things about NHibernate, thanks
Scotty,
NH isn't trying to generate the FK on the fly, it is complaining because you have an invalid definition. You must have the same number of columns on both.
Comment preview