-->
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.  [ 10 posts ] 
Author Message
 Post subject: Inheritance mapping problem
PostPosted: Fri May 05, 2006 5:31 pm 
Newbie

Joined: Thu Mar 16, 2006 12:35 pm
Posts: 17
Hibernate version:
last
Mapping documents:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:nhibernate-mapping-2.0">
   <class name="People, mapping" table="people">
      <id name="id" column="id_people" unsaved-value="0">
         <generator class="sequence" />
      </id>

      <property name="name" column="name"/>
      
      <joined-subclass name="Doctor, mapping" table="missionary">
         <key column="people_id"/>
      </joined-subclass>

      <joined-subclass name="Policeman, mapping" table="policeman">
         <key column="people_id"/>
      </joined-subclass>
      
      
   </class>
</hibernate-mapping>


<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:nhibernate-mapping-2.0">
   <class name="Doctor, mapping" table="doctor">
      <id name="id" column="id_doctor" unsaved-value="0">
         <generator class="sequence" />
      </id>
      
   </class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:nhibernate-mapping-2.0">
   <class name="Policeman, mapping" table="policeman">
      <id name="id" column="id_policeman" unsaved-value="0">
         <generator class="sequence" />
      </id>
      
   </class>
</hibernate-mapping>

Name and version of the database you are using:
Oracle 10 g

Hello

The problem is that I can only save a People object as a Doctor or a Policeman without saving a People as a Doctor and as a Policeman object. If I do that :

Doctor d = new Doctor();
saveObject(d);

Policeman p = new Policeman();
p.id = d.id;
saveObject(p);

I expected that a People object with the status of Doctor is save in the database (that's ok) and that the Policeman object is saved too but it's not the case because NHibernate make an update query instead of inserting a new row in the Policeman table.

What must I change in order to save a People as a Policeman and as a Doctor ?

Thanks in advance


Top
 Profile  
 
 Post subject:
PostPosted: Sat May 06, 2006 2:46 pm 
Newbie

Joined: Thu Mar 16, 2006 12:35 pm
Posts: 17
I have read all the documentation here http://www.hibernate.org/hib_docs/nhibe ... tance.html but I don't find information of what I want to do.

Is is possible or is it a limitation of NHibernate because in UML it's really common to have in an UML diagramm a schema like that :

People
Policeman | Doctor

With a master class People and two subclass, Policeman and Doctor who inherit of People and where a sub-class object (like a policeman object) can be a member of the other sub-class (Doctor here) and this is NOT multiple inheritance !

Have someone the solution or is it impossible to create such mapping with NHibernate ?


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 07, 2006 4:42 am 
Regular
Regular

Joined: Fri Jul 29, 2005 9:46 am
Posts: 101
Hi!
I am not sure if I understood you...

Quote:
Is is possible or is it a limitation of NHibernate because in UML it's really common to have in an UML diagramm a schema like that :

People
Policeman | Doctor


I guess by that you mean that:
Policeman is (inherits from) People
Doctor is (inherits from) People


Then you say:
Quote:
With a master class People and two subclass, Policeman and Doctor who inherit of People and where a sub-class object (like a policeman object) can be a member of the other sub-class (Doctor here) and this is NOT multiple inheritance !


Now... you say that you want an object be both of type doctor and of type policeman... and "that is NOT multiple inheritance"... mmm... IMHO it IS multiple inheritance (therefore it is not an NHibernate limitation... is a .NET limitation)

Maybe you shouldnt be using inheritance at all, maybe you should be using composition:

Person to One Relationship to Doctor
Person to One Relationship to Policeman

Or, if all doctors are policemen, but not all policemen are doctors and they are both people (this way is not Multiple Inheritance):

Policeman is (inherits from) People
Doctor is (inherits from) Policeman

Of course... maybe I didn't understood your question... but I hope this helped


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 07, 2006 4:58 am 
Newbie

Joined: Thu Mar 16, 2006 12:35 pm
Posts: 17
Yes you understood correctly what I want.

The problem is that a People can be a Policeman AND a Scientist or not. A People can be a Scientist AND a Policeman.

So what I want if that when I do :
Code:
Policeman p = new Policeman();
saveObject(p);

-> that's ok, NHibernate add a row in the people table and a row in the policeman table who has a link with the master table people.

After that I do for example :
Code:
Scientist s = new Scientist();
s.id = p.id;

-> here is the problem. The Scientist object is not save in the database. I expected that a new row in the scientist table with a link with the master table people with the ID of the policeman object would be inserted but NHibernate detect that the ID of the Scientist object is already save in the database so he do an UPDATE query instead of inserting a new row in the scientist table !

What I want with my code is that :
Nhibernate add a new row in the master table people, in the sub-table Policeman (that's ok) AND in the Scientist table (that's the problem). So a people could be a policeman AND a scientist and that's not multiple inheritance because the Scientist, Policeman classes inherit of only one class : People.

Is it clear enough ?


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 07, 2006 6:19 am 
Regular
Regular

Joined: Fri Jul 29, 2005 9:46 am
Posts: 101
Hi!

Quote:
The problem is that a People can be a Policeman AND a Scientist or not. A People can be a Scientist AND a Policeman.


Then definitely you should be using composition instead of inheritance:
Person to One Relationship to Doctor
Person to One Relationship to Policeman

Quote:
So a people could be a policeman AND a scientist and that's not multiple inheritance because the Scientist, Policeman classes inherit of only one class : People.


I am sad to tell you, but it is multiple inheritance, because you want your people object to be at the same time of the types of two different classes (Policeman and Doctor) and to do that, you would need a third type, a type that inherits from both Policeman and Doctor, and that would have to be the type of your object.

Imagine you are not working with NHibernate, just plain C#, and you will see that what you want is plain impossible to do (without composition or multiple inheritance):

Code:
Policeman pol = new Policeman();
Policeman doc = new Doctor();

Person p = por; // Fine it works because a Policeman is a Person
Person d = doc; // Fine it works because a Doctor is a Person


But then try:
Code:
Policeman cop = new Doctor(); //It doesn't work
Doctor medic = (Doctor) pol; //It doesn't work AFAIK it doesn't compile, but if it does, it will throw an InvalidCastException on runtime


You see? if it can't be done in C#, it can't be done in NHibernate. It would of course work in unmanaged C++ (by creating a new DoctorPolice class that inherits from both Police and Doctor, but NHibernate wasn't designed to work with unmanged C++)


Last edited by luxspes on Sun May 07, 2006 6:36 am, edited 4 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Sun May 07, 2006 6:24 am 
Newbie

Joined: Thu Mar 16, 2006 12:35 pm
Posts: 17
Ok thanks I will use a composition so.

Good day ;)


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 07, 2006 6:33 am 
Regular
Regular

Joined: Fri Jul 29, 2005 9:46 am
Posts: 101
Yes, I guess that is your best option NHibernate just can't go beyond C# ;)


Top
 Profile  
 
 Post subject: Roles
PostPosted: Mon May 08, 2006 8:42 am 
Newbie

Joined: Thu May 04, 2006 5:51 am
Posts: 7
If it helps, think of it as a Person being able to play more than one Role.

Therefore, a Person may have many Roles.

A particular instance of a Role can be played by one person.

Therefore Policeman, Doctor, etc would inherit from Role and not from Person. Role would have an association to Person.


Top
 Profile  
 
 Post subject: Re: Roles
PostPosted: Mon May 08, 2006 10:05 am 
Newbie

Joined: Thu Mar 16, 2006 12:35 pm
Posts: 17
awilkins wrote:
If it helps, think of it as a Person being able to play more than one Role.

Therefore, a Person may have many Roles.

A particular instance of a Role can be played by one person.

Therefore Policeman, Doctor, etc would inherit from Role and not from Person. Role would have an association to Person.


Godd idea but not good in my case because in your example, role would not inherit of People and that's the problem because all attributes of People exist in Policeman and Scientist. If Policeman and Scientist would inherit of Role and Role have an association to Person I would not able to use attributes of Personne in the Policeman and Scientist class.

Has anobody another idea ?


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 08, 2006 1:27 pm 
Expert
Expert

Joined: Fri May 13, 2005 5:56 pm
Posts: 308
Location: Santa Barbara, California, USA
Just weighing in here...

"Favor composition over inheritance." Remember that little goodie from class? In this instance I have to agree that you are trying multiple inheritance-- not possible in C# or Java (yet). I, personally, would encourage you to think about re-modeling so you have a Person object and a person has a one-to-many collection of Roles.

Code:
<class name="Person" table="Person">
   <id name="id" column="PersonID">
      <generator class="identity" />
   </id>
   <version name="version" />
      
   <property name="FirstName" column="FirstName" type="String" not-null="true" />
   <property name="LastName" column="LastName" type="String" not-null="true" />

   <bag name="Roles" table="Role">
      <key column="PersonID" />
      <one-to-many class="Role" />
   </bag>
</class>


-devon


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 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.