i have not had time to test it, but if it does not cause errors when I
do, I will commit it.  I'm taking a 4 day vacation starting tomorrow, so
it won't be real soon.

john mcnally

On Wed, 2002-07-03 at 08:23, Steve Davis wrote:
> Is there any interest in this patch? If so, could
> someone give me a status?  Thanks.
> 
> -----Original Message-----
> From: Steve Davis 
> Sent: Thursday, June 20, 2002 5:26 PM
> To: Turbine Torque Developers List
> Subject: RE: [PATCH] Support recursive foreign key relationships
> 
> 
> After much more discussion about self-referencing foreign
> keys and how it should be implemented, here is what I came
> up with.  The getParent, getChildren methods would not be
> appropriate because the nature of what we are discussing is
> modeling a general Directed Graph.  
> 
> The nature of the self-referencing relationships are not 
> necessarily that of Parent and Children. Also, there can be 
> cases where there are multiple self-referencing foreign keys 
> in the same table. For that situation the code would break 
> because the template would generate multiple getParent, 
> getChildren methods.
> 
> The "RelatedBy" methods do not have this multiple foreign
> key issues because they include the column name that defines 
> the foreign key relationship.  I think for the situation where
> the local table and foreign table map to different object types, 
> the "RelatedBy" methods are fairly clear.  For example suppose we
> have two tables FOO and BAR that map to objects Foo and Bar and
> Foo has a foreign key A_BAR_ID that maps to BAR's BAR_ID.
> 
> The Foo object has the method 
>  
>   getBarRelatedByABarId()
> 
> In this case you expect it to return the object of type Bar 
> where "this" Foo's A_BAR_ID matches the Bar's BAR_ID.
> 
> The Bar object has the method
> 
>   getFoosRelatedByABarId()
> 
> Which would return a List of all the Foo objects where 
> "this" Bar object's BAR_ID matches a the Foos' A_BAR_ID.
> 
> Some confusion could occur for the objects with self-referencing
> foreign keys.  In the case of an table FOO for object Foo which 
> has a foreign key ANOTHER_FOO_ID that maps to another Foo's FOO_ID.
> You would get the methods 
> 
>    getFooRelatedByAnotherFooId()
> 
> and
> 
>    getFoosRelatedByAnotherFooId()
> 
> I think the first method is still fairly clear but the second 
> is kind of confusing. In the current template the first method
> is being generated for self-referencing foreign keys but the 
> second is not.  Since it is not currently being generated I 
> propose we make the method name more explicit.  The scheme I
> came up with is 
> 
>   get<Object_Type>sWhose<Foreign_Key_Java_Name)IsThis(Primary_Key_Java_Name).
> 
> So for my Foo example this would be
>  
>   getFoosWhoseAnotherFooIdIsThisFooId()
> 
> This explicitly states the foreign key relationship so there
> is less confusion. I am not fond of the method names but I 
> was not clever enough to come up with a better one that explicity
> states the object relationships.  I would assume that people
> would add wrapper methods to make the relationships clearer.
> For my case where I have Folder object that has a foreign key
> reference to a parent folder I would wrap the method
> 
>   getFoldersWhoseParentIDIsThisFolderID() 
> 
> with the method
> 
>   getChildren()
> 
> to make it easier to use.  If anyone has a better naming scheme
> let me know and I will use it.  
> 
> A patch for the Object.vm template is attached and included below.
> 
> -- Steve Davis
> 
> =========================  Begin Patch ============================
>  
> Index: src/templates/om/Object.vm
> ===================================================================
> RCS file: /home/cvspublic/jakarta-turbine-torque/src/templates/om/Object.vm,v
> retrieving revision 1.33
> diff -u -r1.33 Object.vm
> --- src/templates/om/Object.vm        13 Jun 2002 18:25:23 -0000      1.33
> +++ src/templates/om/Object.vm        20 Jun 2002 16:44:21 -0000
> @@ -161,18 +161,27 @@
>                #set ( $varName = "a$tblFK.JavaName" )
>              #end
>  
> +     // $varName references the $tblFK.JavaName pointed to by the 
> +        // foreign key $col.JavaName.
>          if ($varName != null && !Objects.equals(${varName}.get${colFK.JavaName}(), 
>v))
>          {
>              $varName = null;
>          }
>            #end
>  
> +
>            #foreach ($fk in $col.Referrers)
>              #set ( $fkColName = $fk.ForeignLocalMapping.get($col.Name) )
>              #set ( $tblFK = $fk.Table )
> -            #if ( !($tblFK.Name.equals($table.Name)) )
>                #set ( $colFK = $tblFK.getColumn($fkColName) )
> -              #if ($colFK.isMultipleFK())
> +
> +              ## Check to see if this is a self-referencing foreign key
> +              ## If it is, then the name of the collection of objects is
> +              ## different to be more explicit about the relationship.
> +              #if ( $tblFK.Name.equals($table.Name) )
> +                #set ( $relatedToCol = $tblFK.getColumn(${col.Name}).JavaName )
> +                #set ( $collName = 
>"coll${tblFK.JavaName}sWhose${colFK.JavaName}IsThis${relatedToCol}" )
> +              #elseif ($colFK.isMultipleFK())
>                  #set ( $collName = "coll${tblFK.JavaName}sRelatedBy$colFK.JavaName" 
>)
>                #else
>                  #set ( $collName = "coll${tblFK.JavaName}s" )
> @@ -187,7 +196,6 @@
>                            .set${colFK.JavaName}(v);
>                    }
>                }
> -            #end
>            #end
>          #end
>       }
> @@ -332,13 +340,27 @@
>   ##
>   #foreach ($fk in $table.Referrers)
>    #set ( $tblFK = $fk.Table )
> -  #if ( !($tblFK.Name.equals($table.Name)) )
>     #set ( $className = $tblFK.JavaName )
>     #set ( $relatedByCol = "" )
> +
>     #foreach ($columnName in $fk.LocalColumns)
>      #set ( $column = $tblFK.getColumn($columnName) )
> -    #if ($column.isMultipleFK())
> -        #set ($relatedByCol= "$relatedByCol$column.JavaName")
> +    #if ($column.isMultipleFK() || $tblFK.Name.equals($table.Name) )
> +      #set ($relatedByCol= "$relatedByCol$column.JavaName")
> +      #if ( $tblFK.Name.equals($table.Name) )
> +
> +        ## This means we have a self-referencing foreign key. We
> +        ## will need to build more explicit method names so get
> +        ## "related to" column in addition to the "related by" column.
> +
> +        #set ( $colFKName = $fk.LocalForeignMapping.get($columnName) )
> +
> +        ## This will get the "foreign" table column name but since
> +        ## the foreign and local table names are the same we can 
> +        ## still get the column from this table
> +
> +        #set ( $relatedToCol = $tblFK.getColumn( $colFKName ).JavaName )
> +      #end 
>      #end
>     #end
>  
> @@ -347,9 +369,19 @@
>      #set ( $relCol = "${className}s" )
>      #set ( $relColMs = $className )
>     #else
> -    #set ( $suffix = "RelatedBy$relatedByCol" )
> -    #set ( $relCol= "${className}sRelatedBy$relatedByCol" )
> -    #set ( $relColMs= "${className}RelatedBy$relatedByCol" )
> +    #if ( $tblFK.Name.equals($table.Name) )
> +     #set ( $suffix = "RelatedBy$relatedByCol" )
> +
> +     ## If this is a self-referencing foreign key then make the 
> +     ## relationship identifier more explicit for clarity. 
> +
> +     #set ( $relCol= "${className}sWhose${relatedByCol}IsThis${relatedToCol}" )
> +     #set ( $relColMs= "${className}Whose${relatedByCol}IsThis${relatedToCol}" )
> +    #else
> +     #set ( $suffix = "RelatedBy$relatedByCol" )
> +     #set ( $relCol= "${className}sRelatedBy$relatedByCol" )
> +     #set ( $relColMs= "${className}RelatedBy$relatedByCol" )
> +    #end
>     #end
>     #set ( $collName = "coll$relCol" )
>  
> @@ -569,7 +601,7 @@
>  
>          return $collName;
>      }
> -  #end #end #end #end
> +  #end #end #end 
>  
>  ## ===========================================================
>  #*
> @@ -911,23 +943,43 @@
>   #if ($complexObjectModel)
>    #foreach ($fk in $table.Referrers)
>       #set ( $tblFK = $fk.Table )
> -     #if ( !($tblFK.Name.equals($table.Name)) )
>          #set ( $className = $tblFK.JavaName )
>          #set ( $relCol = "" )
> +        #set ( $relatedToCol = "" )
>          #foreach ($columnName in $fk.LocalColumns)
>              #set ( $column = $tblFK.getColumn($columnName) )
> -            #if ($column.isMultipleFK())
> -                #set ( $relCol = "$relCol$column.JavaName" )
> +            #if ($column.isMultipleFK() || $tblFK.Name.equals($table.Name) )
> +              #if ( $tblFK.Name.equals($table.Name) )
> +                ## This means we have a self-referencing foreign key. We
> +                ## will need to build more explicit method names so get
> +                ## "related to" column in addition to the "related by" column.
> +
> +                #set ( $colFKName = $fk.LocalForeignMapping.get($columnName) )
> +
> +                ## This will get the "foreign" table column name but since
> +                ## the foreign and local table names are the same we can 
> +                ## still get the column from this table.
> +
> +                #set ( $relatedToCol = $tblFK.getColumn( $colFKName ).JavaName )
> +
> +              #end
> +              #set ( $relCol = "$relCol$column.JavaName" )
>              #end
>          #end
>  
> +
>          #if ($relCol == "")
>              #set ( $relCol = "${className}s" )
>          #else
> +          #if ( $tblFK.Name.equals($table.Name) )
> +            #set ( $relCol = "${className}sWhose${relCol}IsThis${relatedToCol}" )
> +          #else
>              #set ( $relCol = "${className}sRelatedBy$relCol" )
> +          #end
>          #end
>          #set ( $collName = "coll$relCol" )
>  
> +
>            if ($collName != null)
>            {
>                for (int i = 0; i < ${collName}.size(); i++)
> @@ -935,7 +987,6 @@
>                    ((${className}) ${collName}.get(i)).save(con);
>                }
>            }
> -     #end
>    #end
>   #end
>    #if ($complexObjectModel)
> @@ -1139,13 +1190,27 @@
>    #set ( $list = "List " )
>    #foreach ($fk in $table.Referrers)
>      #set ( $tblFK = $fk.Table )
> -    #if ( !($tblFK.Name.equals($table.Name)) )
>          #set ( $className = $tblFK.JavaName )
>          #set ( $relCol = "" )
> +        #set ( $relatedToCol = "" )
>          #foreach ($columnName in $fk.LocalColumns)
>              #set ( $column = $tblFK.getColumn($columnName) )
> -            #if ($column.isMultipleFK())
> -                #set ( $relCol = "$relCol$column.JavaName" )
> +            #if ($column.isMultipleFK() || $tblFK.Name.equals($table.Name) )
> +              #if ( $tblFK.Name.equals($table.Name) )
> +                ## This means we have a self-referencing foreign key. We
> +                ## will need to build more explicit method names so get
> +                ## "related to" column in addition to the "related by" column.
> +
> +                #set ( $colFKName = $fk.LocalForeignMapping.get($columnName) )
> +
> +                ## This will get the "foreign" table column name but since
> +                ## the foreign and local table names are the same we can 
> +                ## still get the column from this table
> +
> +                #set ( $relatedToCol = $tblFK.getColumn( $colFKName ).JavaName )
> +
> +              #end
> +              #set ( $relCol = "$relCol$column.JavaName" )
>              #end
>          #end
>  
> @@ -1153,8 +1218,13 @@
>              #set ( $pCollName = "${className}s" )
>              #set ( $pCollNameNoS = "${className}" )
>          #else
> -            #set ( $pCollName = "${className}sRelatedBy$relCol" )
> -            #set ( $pCollNameNoS = "${className}RelatedBy$relCol" )
> +            #if ( $tblFK.Name.equals($table.Name) )
> +              #set ( $pCollName = 
>"${className}sWhose${relCol}IsThis${relatedToCol}" )
> +              #set ( $pCollNameNoS = 
>"${className}Whose${relCol}IsThis${relatedToCol}" )
> +            #else
> +              #set ( $pCollName = "${className}sRelatedBy$relCol" )
> +              #set ( $pCollNameNoS = "${className}RelatedBy$relCol" )
> +            #end
>          #end
>  
>          ${list}v = get${pCollName}();
> @@ -1165,7 +1235,6 @@
>              ((Persistent) v.get(i)).setNew(true);
>          }
>          #set ( $list = "" )
> -    #end
>    #end
>    copyObj.setNew(true);
>  #end
> 
> =========================  End Patch ============================
>  
> 
> -----Original Message-----
> From: Scott Finnerty 
> Sent: Friday, June 14, 2002 9:14 AM
> To: Turbine Torque Developers List
> Subject: RE: [PATCH] Support recursive foreign key relationships
> 
> 
> Thanks for the discussion - we considered the comments and suggestions and
> came up with the following:
> 
> 1) Create, in the case of a self-referring foreign key only, convenience methods
>    that are named less ambiguously - we suggest getParent and 
>    getChildren.  We are working on the necessary template modification.
> 
> 2) The naming convention "RelatedBy" is used for clarity and to avoid method 
>    name-collision when a particular column participates in more than one 
>    foreign key.  Its use on self-referring foreign keys is not technically 
>    necessary or consistent.  We perpetuated the use of RelatedBy because it was 
>    already used in the template when generating the additional accessors for 
>    an attribute that is also a foreign key in other tables.  (The patch we 
>    submitted originally added the accessor for the foreign key when it was 
>    self-referring - i.e., the get children method.)
> 
>    So it seems there is a choice:
> 
>    a) Remove the use of "RelatedBy" for self-referring foreign keys - this would
>       change method names as they have previously existed.  We will mitigate the
>       impact by continuing to generate the "RelatedBy" form of the methods and 
>       deprecate them.
> 
>    - or -
> 
>    b) Continue the use of RelatedBy for self-referring foreign keys.
> 
> If everyone/anyone will indicate their preference, we'll submit an appropriate
> patch.
> 
> Thanks
> Scott Finnerty
> 
> -----Original Message-----
> From: John McNally [mailto:[EMAIL PROTECTED]]
> Sent: Thursday, June 13, 2002 3:36 PM
> To: Turbine Torque Developers List
> Subject: RE: [PATCH] Support recursive foreign key relationships
> 
> 
> On Thu, 2002-06-13 at 13:14, Stephen Haberman wrote:
> > > The table has a self-referential key to set up parent/child
> > > relationships.  The method getScarabModulesRelatedByParentId is a bit
> > > ambiguous.  When writing the template I was thinking a method named
> > like
> > > this should return results similar to a method named getParentModules.
> > > What it will return is ChildrenModules.  This is the reason for not
> > > generating these methods.  If others do not find this confusing, I am
> > ok
> > > with the patch.
> > 
> > I agree that it's not the clearest thing in the world, but I would hope
> > users would get it after a few tests, even if they don't at first.
> > 
> > Given that you already trap for this parent/child foreign key reference
> > situation, could you implement getParentModules/getChildModules instead
> > of the ambiguous getModulesRelatedByParentId? I'm not familiar enough
> > with the template to know whether it's possible or not and could be done
> > generally for all (most) situations.
> > 
> 
> I think the method internals could be done generally.  I'm not sure how
> easy it is to generate a suitable method name generally.  The other
> method (getParentModules) will require using aliases which had not been
> added to criteria when i first coded the templates, but it has since
> been added.
> 
> john
> 
> 
> --
> To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
> 
> 
> --
> To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
> 
> 
> --
> To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
> 



--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to