-->
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.  [ 8 posts ] 
Author Message
 Post subject: how to create a mapping XML file if there is no primary key?
PostPosted: Thu Jan 26, 2006 6:25 pm 
Beginner
Beginner

Joined: Thu Jan 12, 2006 7:38 pm
Posts: 25
Hi All,

I am facing a problem in mapping.

i have a table that dont have any primary key.

When you create a mapping XML file , how will you specify??.

i tried with out using <id> tag,
like this <id></id> blank tag .

but it fails , shows error..


so how to create a mapping file , if there is no primary key.


thanks in advance
Gopal.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 26, 2006 6:47 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
If it's a "top level" class (one that you'll want to be able to manipulate on its own and not only in a collection) then it needs an id. It doesn't strictly have to be the DB's primary key for the table, but it does have to be unique. You must put a valid id in your mapping.

Bags and idbags don't have this requirement, but they're only available as collections.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 26, 2006 6:56 pm 
Beginner
Beginner

Joined: Thu Jan 12, 2006 7:38 pm
Posts: 25
Hi Tenwit,

I didnt understand what you are saying...

I have a parent table with primary key , and i have a child table.

in that child table there is no primary key, only foreign key is present.


so when you create a mapping file for the child table , how will you create.


i tried without using <id> tag , it was showing error.

then i tried with blank <id></id> then no error, but fails to return.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 26, 2006 8:48 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
The id tag doesn't have to refer to a primary key column: it can refer to anything that uniquely describes the row. Any column or group of columns that identify the row may be used. If your problem table has a one-to-one relationship with another table, then you can use the FK column as the id. If there's a many-to-one relationship, you'll need another column.

You may also find that you don't need an independent mapping for it, you may be able to use a component.

If you post the shape and relationship of the two tables in question, I can come up with a usable mapping for you. Don't forget to use the code tag, if you need it.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 26, 2006 9:23 pm 
Beginner
Beginner

Joined: Thu Jan 12, 2006 7:38 pm
Posts: 25
Hi tenwit,

Thanks for your reply.

Yes My Table contain one-to-many relationship. And i found a solution for this also. If possible please verify my solution.

the way i did is in my child mapping file is
<class name="table2" table="TABLE2" discriminator-value="table2">
<id name="triggerId" column="TRIGGER_ID" type="string">

</id>
<many-to-one name="table1" column="TRIGGER_ID" insert="false" update="false" class="Table1"/>
</class>


here TRIGGER_ID is the foreign key for table2 and it is a primary key for table1.

and i added getter and setter method for that triggerId. it works fine.

please let me know the way i did is right or not???


thanks in advance
Gopal


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 26, 2006 9:50 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
Yes, that's correct (though you forgot to use the code tag). You haven't described the shape of table1. I'll make a guess though. Assuming that table1 has TRIGGER_ID as the foreign key, and an INSERT_DATE column to make the row unique, then you'd want do to two things:

1) Change your many-to-one mapping in table2 to include property-ref="TriggerID", so that it doesn't try to join on your ID (which will have two columns, so won't join to table2 which only has one column available, TRIGGER_ID).

2) Set up your table1 mapping like this:
Code:
<class name="table1" ...>
  <composite-id>
    <key-many-to-one name="Table2" class="Table2"  column="TRIGGER_ID"/>
    <key-property name="InsertDate" type="date" column="INSERT_DATE"/>
    ...
  </composite-id>
  ...
</class>

Obviously, this applies only if FK/Date make up your unique id for table1. You haven't said what makes up the unique id: perhaps this solution isn't appropriate.

The are other ways of achieving the same thing. I would prefer to use a <list> mapping in table2, containing a component: that way you don't need a separate mapping for table1. You'll have to show me the shape of table1 and table2 before I can determine if that's a better solution for you.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 27, 2006 12:34 pm 
Beginner
Beginner

Joined: Thu Jan 12, 2006 7:38 pm
Posts: 25
HI Tenwit,

My table1 contains:
Code:
<hibernate-mapping package="com.test.temp.model">
   <!-- -->
   <class name="table1" table="TABLE1" discriminator-value="table1">
      <id name="triggerId" column="TRIGGER_ID" unsaved-value="0" type="string">
        <generator class="native"/>
      </id>
      
    <property name="documentId" column="DOCUMENT_ID" not-null="false" type="string"/>
   <property name="clientId" column="CLIENT_ID" not-null="false" type="string"/>
   <property name="application" column="APPLICATION" not-null="false" type="string"/>

<set name="listAll" inverse="false" lazy="false" cascade="all" table="TABLE2">
   <key column="TRIGGER_ID"/>
   <one-to-many class="com.test.temp.model.Table2"/>
   </set>

</class>   
</hibernate-mapping>

My table2 contains:

Code:
<hibernate-mapping package="com.test.temp.model">
   <!-- -->
   <class name="Table2" table="TABLE2" discriminator-value="Table2">
      <id name="triggerId" column="TRIGGER_ID" type="string">
      
   </id>
      
    <property name="serialNo" column="SERIAL_NO" not-null="false" type="string"/>
    <property name="subscriptionType" column="SUBSCRIPTION_TYPE" not-null="false" type="string"/>
    <property name="subscriptionDateTime" column="SUBSCRIPTION_DATE" not-null="false" type="date"/>
   <many-to-one name="table1" column="TRIGGER_ID" insert="false"   update="false"  class="Table1"/>   
    </class>
    </hibernate-mapping>

in Table1 TRIGGER_ID is the primary Key
in Table2 TRIGGER_ID is the foreign key (and table2 contains no primary key)


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 29, 2006 4:14 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
Your solution looks good. Though we've mixed up table1 and table2 in the various posts, but you've certainly got the idea. The only problem here is that you're using a set, which can only have one of each element. Sets are better than bags, but for them to work, you'll need to correctly define the hashCode and equals methods to work off a pure business key. SerialNo and SubscriptionDateTime look like likely candidates for the busniess key for table2.

It looks like triggerId+serialNo might be a unique key: if you set that (or whatever is the unique key) up as the primary key on table2, you will probably get some performance benefits.


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