-->
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.  [ 15 posts ] 
Author Message
 Post subject: Best practices for legacy data with no PK
PostPosted: Mon Oct 25, 2004 6:22 pm 
Newbie

Joined: Thu Oct 21, 2004 3:03 pm
Posts: 13
I'm very new to Hibernate, and I've run into an issue dealing with legacy data (in this case DB2/400 running Mapics manufacturing software).

I have a table which has no native primary key, and I am unable to build a unique composite key since in a few cases entire rows are duplicated.

I'm using <composite-id>, and I understand implementing my own equals() and hashCode(). However, since there are duplicate rows, I'm sort of stuck.

It seems if I code equals() and hashCode() to compare at least several of the most important columns, Hibernate returns duplicate Java objects in the list representing the duplicate rows. Is this what I should expect? I suppose I could do a distinct selection (or otherwise omit the dupes).

This table will be read-only, and I'm basically just reading it to present a list of historical data.

Does Hibernate absolutely require a primary key in the case of a read-only table? I of course don't have to use Hibernate, but there are many features I like and would like to utilize.

I've tried omitting <id> and <composite-id> from my mapping file, but I get a SAX parse error (not surprisingly):

Caused by: org.xml.sax.SAXParseException: The content of element type "class" must match "(meta*,(cache|jcs-cache)?,(id|composite-id),discriminator?,(version|timestamp)?,(property|many-to-one|one-to-one|component|dynamic-component|any|map|set|list|bag|idbag|array|primitive-array)*,(subclass*|joined-subclass*))".

I'm running Hibernate version 2.1.6.

Thanks,
Shawn


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 25, 2004 6:32 pm 
Newbie

Joined: Mon Oct 25, 2004 4:34 pm
Posts: 6
I've typically added a new column, delayed the creation of a unique constraint, went through and assign each row a number, and create a constraint after that.

You can easily make it a sequence (for those DBs that support it) and start the sequence after the last number you assigned, then Hibernate can do the automatic creation for you.

Jeff


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 26, 2004 10:05 am 
Newbie

Joined: Thu Oct 21, 2004 3:03 pm
Posts: 13
If I could add a new column, that would be fine, but unfortunately in this case altering the schema is not really an option (many legacy apps use this table). Again, I am not going to update this data, so Hibernate is out of the picture in that regard.

Since I am new to Hibernate and am trying to understand more of the internals, I mainly wanted to know 1) Does Hibernate absolutely always require a primary key, and 2) Is it expected behavior for Hibernate to return the same object instance for items in a list() which evaluate as equal?

Thanks,
Shawn


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 26, 2004 11:42 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
Just map a column or a set of columns uniquely identfying a column as the id.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 26, 2004 12:04 pm 
Newbie

Joined: Thu Oct 21, 2004 3:03 pm
Posts: 13
As I mentioned, I'm using <composite-id> to do this, and again the difficulty is that it is not possible to generate a unique composite key (since entire rows are sometimes duplicated).

Anyway, I will assume the answers to my questions are 1) yes and 2) yes, unless someone can confirm otherwise.

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 26, 2004 12:08 pm 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
Hibernate will not work on a table with no primary-key candidate, as this is a totally broken relational model. If you can't clean up your model somehow (for example create a distinctifying view) you won't be able to use Hibernate.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 26, 2004 12:48 pm 
Newbie

Joined: Thu Oct 21, 2004 3:03 pm
Posts: 13
I understand this model is pitiful, but unfortunately I can't do much about it. I can make this work satisfactorily enough by making several important columns part of the key, and in cases where those columns are duplicate it seems Hibernate gives me the same object (so I wouldn't know if other less-important columns happened to be different).

Thanks for confirming what I was observing. In read-only cases, I am a little surprised Hibernate doesn't have a mechanism however to just give me a result set from a query, regardless of whether there happens to be a primary key candidate.

I'm not picking on Hibernate, I'm just trying to understand how Hibernate thinks. Can you explain why Hibernate insists on a primary key if I don't plan to update the table (or point me to a reference somewhere)? Is it to avoid redundant object creation? Is it for performance? Is it to completely eliminate the possibility of update? I've read everything I can find, with the exception of Hibernate in Action (which I plan to get very soon).

Fortunately, this one table is an exception. Regardless, in real life this crap happens more often than one might think or like.

Thanks again,
Shawn


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 26, 2004 2:04 pm 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
delete duplicates and use all fields as key, there is no use cases for duplicates anyway.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 16, 2005 6:12 am 
Newbie

Joined: Fri Jan 14, 2005 5:17 am
Posts: 6
Why does Hibernate require a primary key?
I am having the exact same problem, and I thought that using a <bag> insetad of a <set> was intended to let me map these cases.

Updating a bag deletes all rows and inserts all rows again, removing the need for an uniqe ID as far as I can see. As I am only going to read from the bag, this has no performace penalty for me.

Bag looks promising, but when the class that I am mapping with the bag _has_ to declare a primary key I cannot see a sensible use for <bag> anymore.

Am I missing something?

Regards,
Karl Ivar Dahl


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 16, 2005 8:39 am 
Newbie

Joined: Fri Jan 14, 2005 5:17 am
Posts: 6
The apparent solution seems to be using <composite-element> in the <bag>. Composite elements does all I need, without the need for a defined primary key.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 16, 2005 8:45 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
you guys with duplicate rows - how do you update/delete one row and not the others ? How do you distinguish these rows ?

just curious ;)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 17, 2005 2:09 am 
Newbie

Joined: Fri Jan 14, 2005 5:17 am
Posts: 6
Quote:
you guys with duplicate rows - how do you update/delete one row and not the others ? How do you distinguish these rows ?


The <bag> implementation deletes all content of the bag on an update,
then inserts everything that is left. So when an element is removed from
the bag, hibernate/DB does not have to know which one it was. It is
definitively a performance killer, but I suspect most uses of bags are
read-only. It is probably other 'legacy' applications that are providing the
data.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 17, 2005 2:18 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
eh ? how was that an answer ?

having in a bag doesnt change how your queries will work against the tables ? still no way of distincting the different rows...

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 17, 2005 2:29 am 
Newbie

Joined: Fri Jan 14, 2005 5:17 am
Posts: 6
Quote:
you guys with duplicate rows - how do you update/delete one row and not the others ? How do you distinguish these rows ?


Seeing that you are part of the Hibernate theam, you probably know how <bag> is implemented better than me :-)

I'll tell a bit of my scenario when it is needed:
I am importing (with Hibernate) a lot of sales transaction logs for a national
transport company. Some of these transactions can be identical (same ticket, same destination etc).
During import a series of chekcs and relation identification are done. If the transaction passes, the data is copied to a
'domain' object with proper object relations that is persisted by Hibernate and used by the rest of the system.

My 'domain' naturally has syntethic keys and relations, but the data I'm importing definitively has not.
So when i'm importing these data I'm basically traversing a <bag> with 'import' objects, copying them to
'domain' objects and persisting them. Hibernate then gives the domain objects an identity
from a DB sequence.

As for the need of identifying which element I would like to delete in a bag, the answer is I don't care which one I
delete as long as the number of identical rows decreases by one :-)

As I stated in a previous post I can probably solve this by using a <bag> with composite-elements.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 17, 2005 2:40 am 
Newbie

Joined: Fri Jan 14, 2005 5:17 am
Posts: 6
Quote:
eh ? how was that an answer ?

having in a bag doesnt change how your queries will work against the tables ? still no way of distincting the different rows...



From the Hibernate reference:
Quote:
Large Hibernate bags mapped with inverse="false" are inefficient and should be avoided; Hibernate can't create, delete or update rows individually, because there is no key that may be used to identify an individual row.
...
Note that the update performance of an <idbag> is much better than a regular <bag>! Hibernate can locate individual rows efficiently and update or delete them individually, just like a list, map or set.


This leads me to believe that Hibernate does not have to know which row I am altering when I pick a random element from the bag. It just empties the bag and saves all elelents as they were new, no matter how small the change to one of the elements was.


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