-->
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.  [ 3 posts ] 
Author Message
 Post subject: Foreign key must to referenced primary key problem
PostPosted: Mon Nov 10, 2003 3:01 am 
Newbie

Joined: Mon Nov 10, 2003 2:48 am
Posts: 8
Location: GE Medical Systems
Here is the error I am getting when attempting to create a sesion:
Quote:
Foreign key must have same number of columns as referenced primary key


How can I make the mapping file below will not generate the above error?

I am running against a MSSql Server 2000 DB.

Below is the mapping file that generates the error:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="com.ge.med.registries.cx1.TCx1ParticipantM" table="T_CX1_Participant_M">
<id column="Participant_ID" name="id" type="java.lang.Long">
<generator class="native"/>
</id>
<property column="ParticipantName" length="100" name="participantname" type="java.lang.String"/>
<property column="ZipPassword" length="50" name="zippassword" type="java.lang.String"/>
<property column="RegistryType" length="50" name="registrytype" type="java.lang.String"/>
<property column="Site_ID" length="10" name="siteId" type="java.lang.Integer"/>
</class>
<class name="com.ge.med.registries.cx1.TCx1PatientT" table="T_CX1_Patient_T">
<id column="PatID" name="id" type="java.lang.Long">
<generator class="native"/>
</id>
<property column="PatFName" length="50" name="patfname" type="java.lang.String"/>
<property column="PatMInit" length="1" name="patminit" type="java.lang.String"/>
<property column="PatLName" length="50" name="patlname" type="java.lang.String"/>
<property column="SSN" length="50" name="ssn" type="java.lang.String"/>
<property column="Gender" length="3" name="gender" type="java.lang.String"/>
<property column="DOB" length="23" name="dob" type="java.util.Date"/>
<property column="PhoneNumber" length="50" name="phonenumber" type="java.lang.String"/>
<property column="Address" length="100" name="address" type="java.lang.String"/>
<property column="City" length="50" name="city" type="java.lang.String"/>
<property column="State" length="50" name="state" type="java.lang.String"/>
<property column="Zip" length="50" name="zip" type="java.lang.String"/>
</class>
<!-- class com.gems.test.TCx1PatientT is maped 1 to 1 with com.gems.test.TA3PatientT -->
<class name="com.ge.med.registries.cx1.TCx1AdmdisT" table="T_CX1_AdmDis_T">
<composite-id>
<key-property column="Admission_ID" length="10" name="admissionId" type="java.lang.Integer"/>
<key-property column="Participant_ID" length="50" name="participantId" type="java.lang.String"/>
<key-property column="PatID" length="10" name="patid" type="java.lang.Integer"/>
</composite-id>
<property column="AdmitDt" length="23" name="admitdt" type="java.util.Date"/>
<property column="DischDt" length="23" name="dischdt" type="java.util.Date"/>
</class>
<!-- class com.gems.test.TCx1AdmdisT is maped 1 to 1 with com.gems.test.TA3AdmdisT -->
<class name="com.ge.med.registries.a31.TA3AdmdisT" table="T_A3_AdmDis_T">
<composite-id>
<key-property column="Admission_ID" length="10" name="admissionId" type="java.lang.Integer"/>
<key-property column="Participant_ID" length="50" name="participantId" type="java.lang.String"/>
<key-property column="PatID" length="10" name="patid" type="java.lang.Integer"/>
</composite-id>
<property column="AdmitSt" length="5" name="admitst" type="java.lang.Short"/>
<property column="Inpat" length="3" name="inpat" type="java.lang.String"/>
<property column="Payor" length="3" name="payor" type="java.lang.String"/>
<property column="Reserve1" length="10" name="reserve1" type="java.lang.String"/>
<property column="Reserve2" length="10" name="reserve2" type="java.lang.String"/>
<property column="Reserve3" length="10" name="reserve3" type="java.lang.String"/>
<property column="CABStat" length="3" name="cabstat" type="java.lang.String"/>
<property column="CABDt" length="16" name="cabdt" type="java.util.Date"/>
<property column="PstEnzCo" length="3" name="pstenzco" type="java.lang.String"/>
<property column="CKPrBAss" length="3" name="ckprbass" type="java.lang.String"/>
<property column="CKPrBase" length="5" name="ckprbase" type="java.lang.Short"/>
<property column="CKPsPAss" length="3" name="ckpspass" type="java.lang.String"/>
<property column="CKPsPeak" length="5" name="ckpspeak" type="java.lang.Short"/>
<property column="TPrBAss" length="3" name="tprbass" type="java.lang.String"/>
<property column="TPrBase" length="5" name="tprbase" type="java.lang.Short"/>
<property column="TPrPAss" length="3" name="tprpass" type="java.lang.String"/>
<property column="TPsPeak" length="5" name="tpspeak" type="java.lang.Short"/>
<property column="PsCreAss" length="3" name="pscreass" type="java.lang.String"/>
<property column="PsCreLev" length="53" name="pscrelev" type="java.lang.Float"/>
<property column="Blood" length="3" name="blood" type="java.lang.String"/>
<property column="SmoCess" length="3" name="smocess" type="java.lang.String"/>
<property column="CardRef" length="3" name="cardref" type="java.lang.String"/>
<property column="MtDCStat" length="3" name="mtdcstat" type="java.lang.String"/>
<property column="DisLoctn" length="5" name="disloctn" type="java.lang.Short"/>
<property column="MtDate" length="16" name="mtdate" type="java.util.Date"/>
<property column="MtCause" length="5" name="mtcause" type="java.lang.Short"/>
<property column="DeathLab" length="3" name="deathlab" type="java.lang.String"/>
<property column="COMPLETE" length="1" name="complete" type="java.lang.String"/>
<property column="SENT" length="1" name="sent" type="java.lang.String"/>
<one-to-one name="coreAdmit" class="com.ge.med.registries.cx1.TCx1AdmdisT" constrained="true" outer-join="false"/>
<many-to-one name="patientRef" class="com.ge.med.registries.a31.TA3PatientT" column="PatID" not-null="true"/>
</class>
<class name="com.ge.med.registries.a31.TA3PatientT" table="T_A3_Patient_T">
<composite-id>
<key-property column="PatID" length="10" name="patid" type="java.lang.Integer"/>
<key-property column="Participant_ID" length="50" name="participantId" type="java.lang.String"/>
</composite-id>
<property column="Race" length="5" name="race" type="java.lang.Short"/>
<one-to-one name="corePatient" class="com.ge.med.registries.cx1.TCx1PatientT" constrained="true" outer-join="false"/>
<bag name="admits" inverse="true" lazy="true" cascade="all">
<key column="PatID"/>
<one-to-many class="com.ge.med.registries.a31.TA3AdmdisT"/>
</bag>
</class>
</hibernate-mapping>
[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 10, 2003 4:43 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 7:19 pm
Posts: 2364
Location: Brisbane, Australia
Your one-to-one class uses a composite key and the target class has a synthetic key. Clearly this is not correct. You need to have the same key as in this case one-to-one is expecting to join over the primary keys of both candidates of the relation. You have a similar issue with your bag mapping. I cannot suggest any more as its impossible to see what would be correct. So review your database structure first (best if you use real foreign keys in the database) then map the relationships appropriately.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 10, 2003 7:08 pm 
Newbie

Joined: Mon Nov 10, 2003 2:48 am
Posts: 8
Location: GE Medical Systems
Thanks for the above information.

I am still having trouble with understanding composite-id's


Below is a sample of the database structure...
Code:
Where Keys = 3 are primary keys, 1 = normal columns.               
T_CX1_Participant_M               
Keys   Column Name   Data Type   Data Size   Precision   
3   Participant_ID   varchar   50   0   
1   ParticipantName   varchar   100   0   
1   ZipPassword   varchar   50   0   
1   RegistryType   varchar   50   0   
1   Site_ID   int   4   10   
               
T_CX1_Patient_T               
3   PatID   int   4   10   
1   PatFName   varchar   50   0   
1   PatMInit   char   1   0   
1   PatLName   varchar   50   0   
1   SSN   varchar   50   0   
1   Gender   tinyint   1   3   
1   DOB   datetime   8   0   
1   PhoneNumber   varchar   50   0   
1   Address   varchar   100   0   
1   City   varchar   50   0   
1   State   varchar   50   0   
1   Zip   varchar   50   0   
               
T_CX1_PtSite_T               
   Keys   Column Name   Data Type   Precision   
   3   PatID   int   4   
   3   Participant_ID   varchar   50   

T_A3_Patient_T      Keys   Column Name   Data Type   Precision
      3   PatID   int   4
      3   Participant_ID   varchar   50
      1   Race   smallint   2


Data flows from T_CX1_Participant_M -> T_CX1_Patient_T -> T_CX1_PtSite_T -> T_A3_Patient_T.

T_CX1_PtSite_T -> links the T_A3_Patient_T via a 1 to 1.
T_CX1_Participant_M links to T_CX1_PtSite_T via a 1 to many.
T_CX1_Patient_T links to T_CX1_PtSite_T via a 1 to many.

Here is the latest mapping XML...
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
   <class name="com.ge.med.registries.cx1.TCx1ParticipantM" table="T_CX1_Participant_M">
      <id column="Participant_ID" name="id" type="java.lang.Long">
         <generator class="assigned"/>
      </id>
      <property column="ParticipantName" length="100" name="participantname" type="java.lang.String"/>
      <property column="ZipPassword" length="50" name="zippassword" type="java.lang.String"/>
      <property column="RegistryType" length="50" name="registrytype" type="java.lang.String"/>
      <property column="Site_ID" length="10" name="siteId" type="java.lang.Integer"/>
      <set name="PtSites" lazy="true" cascade="all" table="T_CX1_PtSite_T">
         <key column="Participant_ID"/>
         <one-to-many class="com.ge.med.registries.cx1.TCx1PtsiteT"/>
      </set>
   </class>
   <class name="com.ge.med.registries.cx1.TCx1PatientT" table="T_CX1_Patient_T">
      <id column="PatID" name="id" type="java.lang.Long">
         <generator class="native"/>
      </id>
      <property column="PatFName" length="50" name="patfname" type="java.lang.String"/>
      <property column="PatMInit" length="1" name="patminit" type="java.lang.String"/>
      <property column="PatLName" length="50" name="patlname" type="java.lang.String"/>
      <property column="SSN" length="50" name="ssn" type="java.lang.String"/>
      <property column="Gender" length="3" name="gender" type="java.lang.String"/>
      <property column="DOB" length="23" name="dob" type="java.util.Date"/>
      <property column="PhoneNumber" length="50" name="phonenumber" type="java.lang.String"/>
      <property column="Address" length="100" name="address" type="java.lang.String"/>
      <property column="City" length="50" name="city" type="java.lang.String"/>
      <property column="State" length="50" name="state" type="java.lang.String"/>
      <property column="Zip" length="50" name="zip" type="java.lang.String"/>
      <set name="PtSites" lazy="true" cascade="all" table="T_CX1_PtSite_T" inverse="true">
         <key column="PatID"/>
         <one-to-many class="com.ge.med.registries.cx1.TCx1PtsiteT"/>
      </set>
   </class>
   <class name="com.ge.med.registries.cx1.TCx1PtsiteT" table="T_CX1_PtSite_T">
      <composite-id>
         <!-- <key-property name="participantId" column="Participant_ID" type="java.lang.String" length="50"/>
         <key-property name="patid" column="PatID" type="java.lang.Integer" length="10"/> -->
         <key-many-to-one name="participantId" class="com.ge.med.registries.cx1.TCx1ParticipantM" column="Participant_ID"/>
         <key-many-to-one name="patid" class="com.ge.med.registries.cx1.TCx1PatientT" column="PatID"/>
      </composite-id>
      <bag name="admits" inverse="true" lazy="true" cascade="all">
         <key column="PatID"/>
         <one-to-many class="com.ge.med.registries.cx1.TCx1PatientT"/>
      </bag>
   </class>
   <class name="com.ge.med.registries.a31.TA3PatientT" table="T_A3_Patient_T">
      <composite-id>
         <key-property column="PatID" length="10" name="patid" type="java.lang.Integer"/>
         <key-property column="Participant_ID" length="50" name="participantId" type="java.lang.String"/>
      </composite-id>
      <property column="Race" length="5" name="race" type="java.lang.Short"/>
      <one-to-one name="coreSite" class="com.ge.med.registries.cx1.TCx1PtsiteT" constrained="true" outer-join="false"/>
   </class>
</hibernate-mapping>


I have attempted to run this java code.
Code:
Transaction tx = sess.beginTransaction();
TCx1ParticipantM part = null;

    TCx1PatientT corePt = new TCx1PatientT();

    try {
      part = new TCx1ParticipantM();
      part.setId(new Long(1212));
      Query q = sess.createQuery("select part from com.ge.med.registries.cx1.TCx1ParticipantM part where part.id =:id");
      q.setProperties(part);
      Iterator it = q.iterate();
      if(!it.hasNext()){
        part.setParticipantname("My Test Participant");
        part.setRegistrytype("ACC3");
        part.setZippassword("DOG");
        sess.save(part);
      }
    }
    catch (HibernateException ex2) {
    }

    corePt.setPatfname(txtFName.getText());
    corePt.setPatlname(txtLName.getText());
    corePt.setPtSites(new TreeSet());
    corePt.getPtSites().add(new TCx1PtsiteT());
    try {
      corePt.setDob(dateFormatter.parse(txtDOB.getText()));
    }
    catch (ParseException ex) {
    }
    corePt.setAddress(txtAddr.getText());
    try {
        sess.saveOrUpdate(corePt);
        tx.commit();
    }
    catch (HibernateException ex1) {
    }


Nothing is getting written into T_CX1_PtSite_T. I would prefer to auto cascade the data into T_CX1_PtSite_T from both T_CX1_Participant_M and T_CX1_Patient_T since they already contain the id's.

Is this possible?
Is there a better way to structure the mapping XML to represent the DB?


David, thanks again for the quick response on the initial topic.
-Al


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