-->
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.  [ 9 posts ] 
Author Message
 Post subject: hibernate.reveng.xml:foreign-key:set creates duplicate sets
PostPosted: Mon Jul 28, 2008 5:32 pm 
Beginner
Beginner

Joined: Mon Jul 28, 2008 4:36 pm
Posts: 24
I'm using Hibernate tools 3.2.2.Beta1 running hbm2hbmxml from ant against MySQL 5.0.51a-community-nt-log

I was working with hibernate.reveng.xml and found that for some reason, when I specify:

Code:
<table catalog="scorecard" name="business_unit">
    <foreign-key constraint-name="parent_id" foreign-catalog="scorecard" foreign-table="business_unit">
        <column-ref local-column="parent_id" foreign-column="id" />
        <many-to-one property="parent" />
        <set property="children" />
    </foreign-key>
</table>


In my resulting .hbm.xml mapping file I get duplicate <set>s for the "children":

Code:
<set name="children" inverse="true">
    ...
<set name="children_1" inverse="true">
    ...


The <many-to-one> is generated perfectly as name="parent" so I'm half-way there. I was not expecting the second set: children_1.

If I specify nothing (no <foreign-key>), I get the correct <many-to-one> and <set> code (one of each), but the property name is businessUnit and businessUnits respectively which would work, but I'd really like to call them parent and children if possible.

For reference, here is the table creation statement (irrelevant fields removed). Notice that it is a self-joining table - I wonder if that has anything to do with it?

Code:
CREATE TABLE `business_unit` (
  `id` bigint(20) unsigned NOT NULL auto_increment,
  `company_id` bigint(20) unsigned NOT NULL,
  `parent_id` bigint(20) unsigned default NULL COMMENT 'Parent business_unit',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `id` (`id`),
  UNIQUE KEY `identifier_unique` (`company_id`,`identifier`),
  KEY `parent_id` (`parent_id`),
  CONSTRAINT `business_unit_ibfk_2` FOREIGN KEY (`parent_id`) REFERENCES `business_unit` (`id`) ON DELETE CASCADE,
) ENGINE=InnoDB AUTO_INCREMENT=62 DEFAULT CHARSET=utf8


What am I doing wrong?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 29, 2008 8:43 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
my guess is that the foreignkey name is spelt differently, e.g. case sensitive.

if we dont find a match we assume you are defining a new foreignkey.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 29, 2008 10:26 am 
Beginner
Beginner

Joined: Mon Jul 28, 2008 4:36 pm
Posts: 24
As a result of your posting, I made the following changes to hibernate.reveng.xml and everything now works just as I had wanted:

Code:
<table catalog="scorecard" name="business_unit">
    <!--
    <foreign-key constraint-name="parent_id" foreign-table="business_unit">
        <column-ref local-column="parent_id" foreign-column="id" />
    -->
    <foreign-key constraint-name="business_unit_ibfk_2">
        <many-to-one property="parent" />
        <set property="children" />
    </foreign-key>
</table>


My two hang-ups were:

1.) I wasn't clear on the difference between the "constraint" name and the "foreign key" name (I'm still not, but now I know one reason why the difference is important).

2.) I hadn't expected the reverse engineering tool to share code with something that would try to create a new constraint while it was reverse engineering my database. This caused me to misread the manual (section 5.2.4.3. <foreign-key>) here:

http://www.hibernate.org/hib_docs/tools ... ering.html

Thank you very much!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 31, 2008 10:22 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
1) constraint-name was chosen since that is what is used in most sql dialects for the name of foreign keys, primary key, unique constraints, check constraints etc.

2) We don't try and create a new constraint, we just interpret a non-matching foreign-key as something you then want to have as foreign-key...usecase is for older mysql or systems run by DBA's that thinks foreign keys are bad - here being able to state what constraints is actually there even though the db says they are not becomes usefull.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 31, 2008 11:16 am 
Beginner
Beginner

Joined: Mon Jul 28, 2008 4:36 pm
Posts: 24
max wrote:
1) constraint-name was chosen since that is what is used in most sql dialects for the name of foreign keys, primary key, unique constraints, check constraints etc.


Constraint-name is perfect - don't change a thing! MySQL uses a separate constraint name and foreign key name. The constraint name has to be unique within the database so it's automatically assigned the tablename_ibfk_1 where the "1" is a sequence number incremented for each new constraint. If I drop and recreate a table in development, but merely add a new column in test, then the sequence numbers could be different in different environments and issuing a command to change a constraint in one environment will change a *different* constraint in another environment. This would be really bad.

To avoid this, I use the following template to declare a foreign key with MySQL InnoDB (the default database, MYISAM ignores the "on-delete cascade" clause):

Code:
CREATE TABLE process (
    ...
    company_id BIGINT UNSIGNED NOT NULL,
    constraint `process_fk_company` FOREIGN KEY (company_id)
        REFERENCES company(id) on delete cascade,
    ...
) ENGINE=InnoDB;


That way I'm sure that the constraint name (which is what I have to reference in the Hibernate file) will not change. My confusion arose from having to sometimes refer to `process_fk_company` as a constraint (when adding a constraint) and sometimes as a foreign key (when dropping a constraint) in MySQL. That's not Hibernate's issue, though a little note to MySQL users in the reverse-engineering documentation for <foreign-key> would be helpful. The note might be something like:

5.2.4.3. <foreign-key>
...
(1) constraint name:
...
MySQL users: The constraint name is not the same as the foreign key name. To find what constraint name is used for a given foreign key, use the SHOW CREATE TABLE command. Constraint names in mysql look like `tablename_ibfk_1`.


If you point me to the proper place to request such a change I can work on getting it added... If you think it's a good idea.

max wrote:
2) We don't try and create a new constraint, we just interpret a non-matching foreign-key as something you then want to have as foreign-key...usecase is for older mysql or systems run by DBA's that thinks foreign keys are bad - here being able to state what constraints is actually there even though the db says they are not becomes usefull.


Oh, OK. So hibernate.reveng thinks I'm trying to declare a foreign key relationship in the mapping file then it finds a foreign key in the database and shows both in the generated file. Makes sense. I can't imagine why someone would want to use a "database" without foreign keys, but I believe it. I've been forced to do worse things in my career.

Thanks so much for reading my posts so carefully and taking the time to clarify these issues.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 01, 2008 11:57 am 
Regular
Regular

Joined: Tue Jul 29, 2008 4:15 pm
Posts: 62
Location: Dallas, TX US
Any idea on how to keep the reverse engineering process, in the Hibernate Tools plugin for Eclipse, from generating unwanted sets in my hbm.xml files?

Thanks!

_________________
pouncilt


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 01, 2008 12:09 pm 
Regular
Regular

Joined: Tue Jul 29, 2008 4:15 pm
Posts: 62
Location: Dallas, TX US
After reading the Hibernate Tools Reference Guide section 5.2.4.3 "<foreign-key>" a little more closely, I discovered that you can limit the set associated to a class during the reverse engineering process.

Now all I have to do is understand the syntax a little more better. Hopefully this post will help me do that.

_________________
pouncilt


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 01, 2008 12:24 pm 
Regular
Regular

Joined: Tue Jul 29, 2008 4:15 pm
Posts: 62
Location: Dallas, TX US
Okay guys. I just wanted to report back and say that because of this post, I am now able to successfully omit set from certain classes.

Thanks a bunch!

_________________
pouncilt


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 05, 2008 4:36 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
glenpeterson wrote:
max wrote:
That's not Hibernate's issue, though a little note to MySQL users in the reverse-engineering documentation for <foreign-key> would be helpful. The note might be something like:

5.2.4.3. <foreign-key>
...
(1) constraint name:
...
MySQL users: The constraint name is not the same as the foreign key name. To find what constraint name is used for a given foreign key, use the SHOW CREATE TABLE command. Constraint names in mysql look like `tablename_ibfk_1`.


If you point me to the proper place to request such a change I can work on getting it added... If you think it's a good idea.


thansk for explaining why you were confused ;)
The place to get these in is to go to jboss tools jira and add the above explanation in a jira for the Documentation component.

Of course providing a patch to the docs would make it even better ;)
the docs source are at http://anonsvn.jboss.org/repos/jbosstoo ... ools/docs/

Quote:
max wrote:
2) We don't try and create a new constraint, we just interpret a non-matching foreign-key as something you then want to have as foreign-key...usecase is for older mysql or systems run by DBA's that thinks foreign keys are bad - here being able to state what constraints is actually there even though the db says they are not becomes usefull.


Oh, OK. So hibernate.reveng thinks I'm trying to declare a foreign key relationship in the mapping file then it finds a foreign key in the database and shows both in the generated file. Makes sense. I can't imagine why someone would want to use a "database" without foreign keys, but I believe it. I've been forced to do worse things in my career.


The primary use case is MySql which did not have foreign keys until recently leaving alot of users with broken dbs and bad practices.

Quote:
Thanks so much for reading my posts so carefully and taking the time to clarify these issues.


No problem!

_________________
Max
Don't forget to rate


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