-->
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.  [ 12 posts ] 
Author Message
 Post subject: Insert into parent table using the object of dependent table
PostPosted: Tue Sep 18, 2007 9:29 am 
Beginner
Beginner

Joined: Tue Sep 11, 2007 5:57 am
Posts: 36
Hello,
I have a table named Individual, which is a generalised table, holding record for all entities like Doctor, patient, user etc. Then I have one more table named Patient with primary key as Patientuid referring to IndividualUid(primary key of Individual). I want to create a new record for patient table, and I do the following

Patient objPatient = new Patient();
objPatient.Individual.FirstName = "xyz";
objPatient.Individual.LastName = "abc";
objPatient.externalID = 1234;
.
.
.
session.save(objPatient);

Unfortunately this didn't work. I expected it to first insert a record in Individual table and then using the newly generated IndividualUid insert a record in Patient. It directly tries to insert into Patient and thus foreign key violation exception is thrown.

I am sure, there has to be some way to achieve this as it know that the record in patient depends on Individual.

Please help me to achieve this?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 18, 2007 9:48 am 
Regular
Regular

Joined: Fri Jan 20, 2006 7:45 pm
Posts: 97
Location: San Antonio, TX
Your mapping should look something like this:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="Name.Space.Individual, Name.Space"
         table="INDIVIDUAL">
   
    <id name="ID" column="INDIVIDUALID" unsaved-value="0">
      <generator class="native">
        <param name="sequence">SEQ_INDIVIDUAL</param>
      </generator>
    </id>

    <!-- Individual properties -->
    <property name="FirstName" column="FIRSTNAME" />
    <property name="LastName" column="LASTNAME" />

    <joined-subclass
      name="Name.Space.Patient, Name.Space"
      table="PATIENT">
      <key column="INDIVIDUALID"/>

      <!-- Patient properties -->
    </joined-subclass>
   
  </class>
</hibernate-mapping>


Also, you don't need a property called ExternalID. Both classes could have a property called ID. In fact, all my domain entities inherit from a class like this:
Code:
public abstract DomainEntity<IdType>
{
   public IdType ID
   {
      get{return id;}
      set{id = value;} //would probably be best to make the setter protected
   }

   ...

   private IdType id;
}


Make sense?

_________________
Dum spiro, spero
-------------------------------
Rate my post if it helps...


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 18, 2007 10:02 am 
Beginner
Beginner

Joined: Tue Sep 11, 2007 5:57 am
Posts: 36
I will check on this, but before that just wanna be sure that I have made myself clear.

ExternalId is just a simple column for the patientID.
The foreign key column is not a integer its uniqueidentifier.
By making the changes in the xml file for the class Individual, will

session.save(objPatient) ;

first insert a row in Individual and then in patient maintaining the foreign key reference?

Also, for this does the patient class need to inherit from Individual?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 18, 2007 10:31 am 
Regular
Regular

Joined: Fri Jan 20, 2006 7:45 pm
Posts: 97
Location: San Antonio, TX
If externalID is for something else, then forget that comment. The example I gave assumes two tables Individual and Patient. The individual has the primary key for all individuals in the system and a Patient shares a primary key with Individual. In the database, the Individual record would be inserted first then the Patient record would be inserted using the key of the Individual. In your class heirarchy, Patient inherits from Individual. Individual could be an abstract class.

As long as both Individual and Patient have uniqueidentifier as their key, all should be well (given this, I assume you are using SqlServer...so you don't need the sequence tag, only generator="native"...unless of course you are using the COMB generator that NHibernate provides [which are sortable GUIDs]).

Does that answer your questions?

_________________
Dum spiro, spero
-------------------------------
Rate my post if it helps...


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 19, 2007 3:41 am 
Beginner
Beginner

Joined: Tue Sep 11, 2007 5:57 am
Posts: 36
Do I need to inherit patient class from Individual?
As I also have one more column in Patient and that's AddressUid. This refers to the Primary key AddressUid of the Address table.

In short I also need to

Patient objPatient = new Patient();
objPatient.Individual.FirstName = "xyz";
objPatient.Individual.LastName = "abc";
objPatient.externalID = 1234;
objPatient.Address.Address1 = "New Lane";
objPatient.Address.City = "Pune";
.
.
.
session.save(objPatient);

So then to make this work I will also need patient class to inherit from Address, which is not possible if it is already inherited from Individual.

Also, how do I make NHibernate generate the primary for any table?

I tried

in Patient.hbm.xml

<id name="PatientUid" column="PatientUid" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="foreign">
<param name="property">Individual</param>
</generator>
</id>

in Individual.hbm.xml

<id name="IndividualUid" column="IndividualUid" type="Guid">
<generator class="guid"/>
</id>

in Address.hbm.xml

<id name="AddressUid" column="AddressUid" type="Guid">
<generator class="guid"/>
</id>

And fortunately it is working fine.
Do you see any problem with this approach?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 19, 2007 11:05 am 
Regular
Regular

Joined: Fri Jan 20, 2006 7:45 pm
Posts: 97
Location: San Antonio, TX
FIGDevelopers wrote:
Do I need to inherit patient class from Individual?
As I also have one more column in Patient and that's AddressUid. This refers to the Primary key AddressUid of the Address table.

In short I also need to

Patient objPatient = new Patient();
objPatient.Individual.FirstName = "xyz";
objPatient.Individual.LastName = "abc";
objPatient.externalID = 1234;
objPatient.Address.Address1 = "New Lane";
objPatient.Address.City = "Pune";
.
.
.
session.save(objPatient);

So then to make this work I will also need patient class to inherit from Address, which is not possible if it is already inherited from Individual.

You don't need to inherit from Address, you'll just need a one-to-one mapping with the Address table. Since the foreign key to Address is on the Patient table this should be pretty easy to do. Patient should inherit from Indivudual only.

FIGDevelopers wrote:
Also, how do I make NHibernate generate the primary for any table?

I tried

in Patient.hbm.xml

<id name="PatientUid" column="PatientUid" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="foreign">
<param name="property">Individual</param>
</generator>
</id>

in Individual.hbm.xml

<id name="IndividualUid" column="IndividualUid" type="Guid">
<generator class="guid"/>
</id>

Look at the sample mapping that I provided above. As you'll see you have a class mapping for the base type Individual. The joined-subclass tag is for specific mappings related to Patient. It assumes that the Patient table has as a primary key the same key value as Individual and that a Patient can't be defined outside of the context of the Individual base table.

Patient's IndividualID has a foreign key dependency on Individual's IndividualID. When you save a new Patient record, NHibernate will first insert a record into Individual while generating the guid primary key. NHibernate will then use the same key to create a Patient record using Individual's primary key for the field specified in the key tag.

All fields that are common to Individual and Patient would have property tags in the Individual's class mapping (this assumes duplication of data between the two tables). Any fields specific to Patient yould have property tags in the joined-subclass section for the Patient class. In your example, this is where the one-to-one mapping to Address would be.

Does that make sense, or would you like me to make another mapping doc?

P.S. Don't forget to mark postings that help you solve your issue.

_________________
Dum spiro, spero
-------------------------------
Rate my post if it helps...


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 24, 2007 1:38 am 
Beginner
Beginner

Joined: Tue Sep 11, 2007 5:57 am
Posts: 36
Sorry for the late reply, actualy I was on leave.

Anyways, I tried it and it is working.
It's also working the way I tried earlier. Which approach would be better?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 24, 2007 10:23 am 
Regular
Regular

Joined: Fri Jan 20, 2006 7:45 pm
Posts: 97
Location: San Antonio, TX
FIGDevelopers wrote:
Sorry for the late reply, actualy I was on leave.

Anyways, I tried it and it is working.
It's also working the way I tried earlier. Which approach would be better?


I assume you are asking about which inheritance approach is most appropriate? I'd say having Patient inherit from Individual (because a Patient BEHAVES AS AN Individual..whereas you don't have the same relationship between Address and Patient).

Let me know if that answers your question.

_________________
Dum spiro, spero
-------------------------------
Rate my post if it helps...


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 26, 2007 1:50 am 
Beginner
Beginner

Joined: Tue Sep 11, 2007 5:57 am
Posts: 36
Thanks a lot for your help.

I have posted one more question at the forum will the title as 'Exposing IsessionFactory object using Remoting' and not received any reply yet. If possible please have a look.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 26, 2007 2:15 am 
Beginner
Beginner

Joined: Tue Sep 11, 2007 5:57 am
Posts: 36
Thanks a lot for your help.

I have posted one more question at the forum will the title as 'Exposing IsessionFactory object using Remoting' and not received any reply yet. If possible please have a look.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 26, 2007 10:35 am 
Regular
Regular

Joined: Fri Jan 20, 2006 7:45 pm
Posts: 97
Location: San Antonio, TX
BTW: Don't forget to rate postings that help you

_________________
Dum spiro, spero
-------------------------------
Rate my post if it helps...


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 03, 2007 10:40 am 
Contributor
Contributor

Joined: Sun Jun 26, 2005 5:03 am
Posts: 51
Location: London, UK
You might have another issue when you get into this a bit further; Patient is actually a role that an Individual plays rather than being a sub-type of it, as is Doctor.

The problem arises is when one of your Doctor's becomes a Paitent; with your model you are forced to create another Individual record to record the information, with a role-based model you can associate another role to the same individual.

_________________
Paul Hatcher
NHibernate Team


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