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]>