-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: howto map many-to-many relation between a class and itself?
PostPosted: Thu Jan 10, 2008 11:59 am 
Newbie

Joined: Tue Nov 20, 2007 12:03 pm
Posts: 13
Hi guys,
My goal is to represent & map the following scenario using NHibernate:
public class Person {
private int _id;
private string _name;
public int ID { get {return _id;} set {_id = value;} }
public string Name { get {return _name;} set {_name = value;} }
}

A table representing Person
CREATE TABLE Person(
Id int NOT NULL,
Name nvarchar(20) default NULL ) ;

A table representing a many to many relation between one Person to another:
CREATE TABLE PersonRelations(
PersonId1 int NOT NULL,
PersonId2 int NOT NULL,
TypeOfRelation nvarchar(20) NOT NULL default 'Friend') ;


======================================
Initially I added a Collection of Person to the Person class:
private IList<Person> _relatedPersons;
public IList<Person> RelatedPersons
{
get { return _relatedPersons; }
set { _relatedPersons = value; }
}

My mapping currently looks like this:
Code:
<class name="Person" table="Persons">
    <id name="Id">
        <column name="ID" />
        <generator class="assigned" />
    </id>
    <property name="Name" />

    <bag name="RelatedPersons" table="personrelations">
        <key column="PersonId1" />
        <many-to-many class="Person" column="PersonId2" />
    </bag>
</class>


This mapping Is ok if I ignore the TypeOfRelation mentioned earlier. It saves the relation in personrelations table and deletes it when a person is deleted.

The problem is me not being able to answer the following question:
Who are John Doe's friends?
I basically need to load a person with a name "John Doe" and in some way define an expression on the relation table, thus getting in the RelatedPersons collection only the persons that relate to him with "Friend" as the type of relation.

There is very little / almost no documentation on this subject.
After a very long search in the forums, Google & nhibernate blogs, I found only one thread that discusses the issue of mapping many-to-many relations of the same class. (ttp://forum.hibernate.org/viewtopic.php?t=969967&start=0&postdays=0&postorder=asc&highlight=)
The above post only scrapes the surface of this subject, but not enough to answer my question.

Is there A way to do This?
Shaul


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 10, 2008 12:35 pm 
Regular
Regular

Joined: Wed Jan 25, 2006 1:11 am
Posts: 118
Location: Copenhagen, Denmark
One suggestion of the top of the head: Introduce a Class representing your relation between persons

class Relation{
public string Type{...}
public Person RelatedTo{...}
public Person Person{...}
}

Then let each person have a bag of Relation classes

You problem is that you have data in the association, in many cases you can use a <map> and have it in a dictionary but as i understand your Model both the same "RelationType" and Person can appear in the collection multiple times for instance:

Person1 Friend
Person1 Coworker
Person2 Friend

so you would have problem using either as a key in a dictionary


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 10, 2008 1:14 pm 
Newbie

Joined: Tue Nov 20, 2007 12:03 pm
Posts: 13
I could create a class like you suggested, but that's like saing Relation is a type when it's actualy an association with propertie/s, moreover it'll force me to perform the association in the application itself.

Any other ideas?

jta wrote:
One suggestion of the top of the head: Introduce a Class representing your relation between persons

class Relation{
public string Type{...}
public Person RelatedTo{...}
public Person Person{...}
}

Then let each person have a bag of Relation classes

You problem is that you have data in the association, in many cases you can use a <map> and have it in a dictionary but as i understand your Model both the same "RelationType" and Person can appear in the collection multiple times for instance:

Person1 Friend
Person1 Coworker
Person2 Friend

so you would have problem using either as a key in a dictionary


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 10, 2008 1:22 pm 
Regular
Regular

Joined: Wed Jan 25, 2006 1:11 am
Posts: 118
Location: Copenhagen, Denmark
But what type should your "RelationType" property be in your model if you dont introduce somewhere the value can be?

You could make your collections a KeyValuePair<string, Person> but i don't know if that is possible and it isn't very pretty


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 13, 2008 5:36 am 
Newbie

Joined: Tue Nov 20, 2007 12:03 pm
Posts: 13
Let's say I'll create a type "RelationType" that has two Person instances and a string property holding the relation type.
An often scenario in my application would be selecting a Person by some criterion, followed by selecting all persons related to him with say "Friend" type relation.

This means I'll have two queries:
1) Select the person from the table
2) Create an instance of "RelationType" and use the person found earlier in order to select the related objects.

Is this how you suggest I should do it?
Should "RelationType" hols an instance of Person or only a Person's ID (PK)?

jta wrote:
But what type should your "RelationType" property be in your model if you dont introduce somewhere the value can be?

You could make your collections a KeyValuePair<string, Person> but i don't know if that is possible and it isn't very pretty


Top
 Profile  
 
 Post subject: Re: howto map many-to-many relation between a class and itse
PostPosted: Mon Jan 14, 2008 4:10 am 
Regular
Regular

Joined: Fri Feb 18, 2005 3:34 am
Posts: 88
Location: Poland/Wrocław
Shaul wrote:
The problem is me not being able to answer the following question:
Who are John Doe's friends?
I basically need to load a person with a name "John Doe" and in some way define an expression on the relation table, thus getting in the RelatedPersons collection only the persons that relate to him with "Friend" as the type of relation.


Doesn't a simple query like following work? After applying a parameter "John Doe", of course.

Code:
from Person p where p.Name = ?

_________________
Please rate this post if you've found it helpfull
Roland


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 14, 2008 6:46 am 
Regular
Regular

Joined: Wed Jan 25, 2006 1:11 am
Posts: 118
Location: Copenhagen, Denmark
Shaul wrote:
Let's say I'll create a type "RelationType" that has two Person instances and a string property holding the relation type.
An often scenario in my application would be selecting a Person by some criterion, followed by selecting all persons related to him with say "Friend" type relation.

This means I'll have two queries:
1) Select the person from the table
2) Create an instance of "RelationType" and use the person found earlier in order to select the related objects.


A person has a collection of RelationType all the relation they have, when you fetch the person you can use either eager or lazy loading to get the list of relation, and you can use ISession.Filter to filter in them.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.