join mapping

3 views
Skip to first unread message

Patrik Lowendahl

unread,
Sep 23, 2009, 4:40:14 AM9/23/09
to nhu...@googlegroups.com
Is there any plans on supporting joins mapping on any other column then the class PK?

I see a lot of legacy where they have used arbitrary columns as the FK, like this example:

[Person]
PersonId

[AdPerson]
PersonId
ObjectSID

[User]
ObjectSID

Doing a projection over this (UserInfo) becomes bothersome and the simplest solution would be something like:

<class name="AdPerson">
  ...
  <join table="Person">
     <key column="PersonId" />
    ...
   </join>
   <join table User>
     <key column="ObjectSID" foreign-key="ObjectSID" />
   ---

For the record, I don't agree with the database model, but this is what I have to work with and a construct like the above would make it a lot more easy to manage.

--
Patrik

Patrik Lowendahl

unread,
Sep 30, 2009, 10:15:58 AM9/30/09
to nhu...@googlegroups.com
Bump

Anne Epstein

unread,
Sep 30, 2009, 10:59:36 AM9/30/09
to nhu...@googlegroups.com
Patrick,
For the sake of argument, let's say join could be used in the way you described.  For the record, it looks like a classic many-to-many setup.  So you end up with a larger entity that contains information for both Person and User. There's nothing on your setup that enforces or even implies as 1-to-one relationship, so let's imagine that a Person (let's call her Anne)  has ended up with multiple users (ajepst and aepstein) mapped in the AdPerson table.  Here's a mockup of what the two joined objects would look like:

AdPerson #1
AdPersonID : 1
PersonID: 5
PersonName: Anne
UserID: 25
UserLogin: ajepst

AdPerson #2
AdPersonID: 2
PersonID: 5
PersonName: Anne
UserID: 26
UserLogin: aepstein

Then, we imagine that we can modify and save each of these objects, just like any other normal nhibernate-connected object (unlike a projection, for instance) . Let's say we change my name in object AdPerson #1

AdPerson #1
AdPersonID : 1
PersonID: 5
PersonName: *Princess Leia* <= look, my new name!
UserID: 25
UserLogin: ajepst

Well, that's great.. but object AdPerson #2 is still around, with this data:

AdPerson #2
AdPersonID: 2
PersonID: 5
PersonName: Anne
UserID: 26
UserLogin: aepstein

a) this is now weird and inconsistent, (I have two different names depending on which object I look at?) and b)... What happens if we were to give me a *different* new name in AdPerson #2? My awesome Leia name gets clobbered. awww. 

This object is identified by AdPerson #2 and using that to understand "sameness".  There's no concept of "well keep track that THIS PART of this object over here is a part of this other object over here, and keep them in sync" .Net can handle this easily with whole objects, that's what Equals is about. But this partial stuff... well, in fact, AdPerson #1 and Adperson #2 aren't really the same idea, and if you did mysteriously change the data in one when you changed it in the other, it would weird, and would probably cause a lot more confusion than it would solve problems.  The core issue is just that in this situation, NHibernate doesn't understand that these two objects are partially the same thing, and it doesn't have a good way of knowing that.  The designers of NH decided to avoid the whole mess by restricting join to a true one-to-one.  That way, duplicate Persons can't show up in conceptually different objects. If it's there, they are also the same object. simple.

Note, if this IS something you want, you could try to implement it, but you'd have to figure a way around the intrinsic problems described above. Me, I'll stick to walking the relations when I need to for this kind of many-to-many layout-NHibernate allows a little bit of divergence from the db structure, but you still want to stay fairly close or you're going to be in some serious pain.. Good luck.

Fabio Maulo

unread,
Sep 30, 2009, 11:35:15 AM9/30/09
to nhu...@googlegroups.com
ORM (object relational mapping):
The POID should be unique inside a class hierarchy or, even better, inside your domain.
A POID should refer uniquely one, and only one, entity instance.

How look your domain?

2009/9/23 Patrik Lowendahl <patrik.l...@gmail.com>



--
Fabio Maulo

Patrik Lowendahl

unread,
Oct 1, 2009, 5:06:20 AM10/1/09
to nhu...@googlegroups.com
This is also an answer in part to Fabio Maulo.

Very valid and good points. I understand the technical difficulties in what I suggest. I can't agree that this has to be a many to many though, let me explain.

There is several scenarios when modeling where entities will look different, a product will not always be a product in all contexts of a system. Product is a very good example of this. In a system (or actually a database) that handles both the PLM part of a company and order part, there will be inconsistency in how you model the subsystems. You do not want to reuse the Product entity from the PLM subsystem into your Order subsystem and often the shape of the information are different in the two contexts.

In the PLM system you might want a very rich product entity while in the Order->OrderLine->ProductInfo case you want a very slim product. In some cases, and I have a couple of those scenarios in my current project, the business looks at the information a bit different in between these context. And I would argue that the model should look like the business looks at it, not as the database relational model has put it for one context (in this case the PLM).

This is the case for my AdPerson / Person example (the real example is actually in three parts). The model that generated that table structure had requirements that made sense for that context. In the context I am right now it doesn't make sense, the business doesn't look at the entity in the same way. They want the information from both tables to be in the same entity, that is how that part of the business looks at it. Not as separate entities.

--
Patrik

Patrik Lowendahl

unread,
Oct 1, 2009, 5:12:30 AM10/1/09
to nhu...@googlegroups.com
"The POID should be unique inside a class hierarchy or, even better, inside your domain."
This statement is leaky. The domain should not care about POID, at all, POID is a storage concern. Not a business concern. I have a longer argument on my old blog about this: http://www.lowendahl.net/showShout.aspx?id=103


"A POID should refer uniquely one, and only one, entity instance."
Yes, but there is nothing that says that there can't be several entities that store their POID in the same table.

See my response to Anne for a bit more info on the last statement.

--
Patrik Löwendahl
http://blog.lowendahl.net
http://twitter.com/lowendahl

Fabio Maulo

unread,
Oct 1, 2009, 10:11:46 AM10/1/09
to nhu...@googlegroups.com
You have forgot the response to my question:
How look your domain?


2009/10/1 Patrik Lowendahl <patrik.l...@gmail.com>



--
Fabio Maulo

Patrik Lowendahl

unread,
Oct 1, 2009, 10:33:42 AM10/1/09
to nhu...@googlegroups.com
One of the full examples for this is:


Tables:

Person
--
PersonId
<name etc>

ADPerson
--
ObjectSid
PersonId


User
--
ObjectSid
IsActive, etc


The domainmodel is:

UserInfo {
    Id (from person table)
    ObjectSid (from adperson table)
    Name (from person table)
    IsActive (from user table)
}

This is part of a list relationship

Order -> OrderLine -> Resonsible : UserInfo

There is a couple of others in this particular system. That are similar to this. We played around with projections, but for this scenario with a deep graph (it's actually deeper then the example) it's really a mess to go about it that way.

--
Patrik
Reply all
Reply to author
Forward
0 new messages