This is a known issue regarding foreign key generation in torque (see
http://www.mail-archive.com/[email protected]/msg06157.htm
l
http://www.mail-archive.com/[email protected]/msg06545.htm
l)
But I can't find a fix for it yet.

Basically the problme is that if a column appeared in more than one
forgien key element, then the wrong code generated. For example, in
schema file, 

<table name="foo">
...
<fk table1><ref1/></fk>
<fk table2><ref1><ref2/></fk>
</table>

in the above case, the BaseTable2.java will have duplicate collection
object for table foo. But if we change the sequence of foreign key, i.e,

<table name="foo">
...
<fk table2><ref1><ref2/></fk>
<fk table1><ref1/></fk>
</table>

then BaseTable2.java compiles but BaseTable1.java will use both ref1 and
ref2 as the joint select key. I enclosed a modified version of
project-schema.xml for testing.

After some debugging, I found out the problem is with
Table.getForeignKey(String col). This method assumes one column only in
one foreign key. If one column in more than one foreign key, it will
return the wrong foreign key depending the sequence of the foreign key.

There are several fixes:
1) check the returned ForeignKey object to make sure its
foreignTableName is the same as the foreign table you want to use. This
is the fix I used in XmlToAppData.java (see enclosed)
2) change the signature of getForeignKey to include a foreign table
name. We can change it to: getForeignKey(String foreignTableName) or
getForeignKey(String col, String foreignTableName). This will break some
existing code. 
3) add a Table.getForeignKey(Table foreignTable) method. This will not
break exsiting code. (see enclosed) 

I think maybe (3) is the best approach.

Howard

Attachment: Table.java.diff
Description: Table.java.diff

Attachment: XmlToAppData.java.diff
Description: XmlToAppData.java.diff

<?xml version="1.0" encoding="ISO-8859-1" standalone="no" ?>
<!DOCTYPE database SYSTEM "http://jakarta.apache.org/turbine/dtd/database.dtd";>

<!-- ==================================================================== -->
<!--                                                                      -->
<!-- E X A M P L E  T O R Q U E  S C H E M A                             -->
<!--                                                                      -->
<!-- ==================================================================== -->

<!-- 
  Note: You must now specify a database name.
-->

<database name="INTERPLANETARY">  
  <table name="CIVILIZATION">
    <column name="CIV_ID" required="true" autoIncrement="true"
            primaryKey="true" type="INTEGER"/>
    <column name="NAME" required="true" type="LONGVARCHAR"/>
  </table>

  <table name="CIV_PEOPLE">
    <column name="CIV_ID" required="true" primaryKey="true" 
            type="INTEGER"/>
    <column name="PEOPLE_ID" required="true" primaryKey="true" type="INTEGER"/>

    <foreign-key foreignTable="CIVILIZATION">
        <reference local="CIV_ID" foreign="CIV_ID"/>
    </foreign-key>
    <foreign-key foreignTable="PEOPLE">
        <reference local="PEOPLE_ID" foreign="PEOPLE_ID"/>
    </foreign-key>
  </table>

  <table name="PEOPLE">
    <column name="PEOPLE_ID" required="true" autoIncrement="true"
            primaryKey="true" type="INTEGER"/>
    <column name="NAME" required="true" size="255" type="VARCHAR"/>
    <column name="PLANET_ID" primaryKey="true" required="true" type="INTEGER"/>
    <column name="SPECIES_ID" primaryKey="true" required="true" type="INTEGER"/>
    <foreign-key foreignTable="SPECIES">
        <reference local="SPECIES_ID" foreign="SPECIES_ID"/>
    </foreign-key>
    <foreign-key foreignTable="PLANET_SPECIES">
        <reference local="SPECIES_ID" foreign="SPECIES_ID"/>
        <reference local="PLANET_ID" foreign="PLANET_ID"/>
    </foreign-key>
  </table>

  <table name="SPECIES">
    <column name="SPECIES_ID" required="true" primaryKey="true" type="INTEGER"/>
    <column name="NAME" required="true" size="255" type="VARCHAR"/>
  </table>

  <table name="PLANET">
    <column name="PLANET_ID" required="true" autoIncrement="true" primaryKey="true" type="INTEGER"/>
    <column name="NAME" required="true" size="255" type="VARCHAR"/>
  </table>

  <table name="PLANET_SPECIES">
    <column name="SPECIES_ID" required="true" primaryKey="true" type="INTEGER"/>
    <column name="PLANET_ID" required="true"  primaryKey="true" type="INTEGER"/>
    <column name="NAME" required="true" size="255" type="VARCHAR"/>
    <foreign-key foreignTable="SPECIES">
        <reference local="SPECIES_ID" foreign="SPECIES_ID"/>
    </foreign-key>
    <foreign-key foreignTable="PLANET">
        <reference local="PLANET_ID" foreign="PLANET_ID"/>
    </foreign-key>
	</table>
</database>  
--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to