Skip to main content
Inspiring
March 20, 2016
Question

Why does EntityLoadByExample() ignore relationships?

  • March 20, 2016
  • 1 reply
  • 485 views

I've been using ORM for a while, but just started getting into using EntityLoadByExample(). I thought this would be great, but I've run into an issue. Say I have an object "Art" and it has a many-to-one relationship to "Artist" (many arts may have the same artist).

So my sample Art object would be like:

component displayname = 'Art' {

     property name='artID' fieldtype='id' generator='identity';

     property name='title' type='string';

     property name='Artist' fieldtype='many-to-one' CFC='Artist' fkcolumn='ArtistID'

}

My sample Artist Object would be like:

component displayname = 'Artist' {

     property name='ArtistID' fieldtype='id' generator='identity';

     property name='Name' type='string';

}

So, lets say I have an artist in my DB:

ArtistIDName
1Monet
2Rembrandt

And let's say I have some "Art" in my DB:

ArtIDtitleArtID
1The Water Lily Pond1
2Woman with a Parasol1
3Poppies1
4The Night Watch2
5The Jewish Bride2

So, I will get the Monet Object:

monet = EntityLoad( 'Artist' , 1 , true );

Then I will create a "new" Art and add in monet as the artist:

myBlankArt = EntityNew( 'Art' , { Artist = monet } );

So, my expectations is that I would be able to run the following code and ONLY get the Art Objects with ArtIDs 1, 2, and 3 (because they have ArtistID 1).

artSearch = EntityLoadByExample( 'Art' , myBlankArt );

However, what happens is I get ALL the Art Objects because it IGNORES the Artist object in my example entity.

Am I complete crazy for expecting this to work? I understand that it might be a limitation of Hibernate, but it is quite frustrating!

I have found a work around by adding the following property to the Art Object:

property name='ArtistID' forumula='select ArtistID';

then adding using the ID in the entity using some somewhat complex code to dynamically pull the objects, then grab their ids,

    public function loadByExample( example ) {

          local.metaData = getMetaData( arguments.example );

          for( local.property in local.metaData.properties ) {

               if( structKeyExists( local.property , 'fieldtype' ) && listFind( 'many-to-one,one-to-one' , local.property.fieldType , ',' ) ) {

                    if( structKeyExists( local.property , 'fkcolumn' ) ) {

                         local.innerObject = arguments.example.getProperty( local.property.name , arguments.example );

                         if( !isNull( local.innerObject ) )

                         {

                              local.id = local.innerObject.getPrimaryKey();

                              if( !isNull( local.id ) )

                              {

                                   arguments.example.setProperty( local.property.fkcolumn , local.id , local.newObject );

                              }

                         }

                    }

               }

          }

          return EntityLoadByExample( arguments.example );

     }

(note: getProperty and setProperty are methods in my base object that all my ORM objects extend that allow me to send in the name of a property and set/retrieve it instead of using the setter/getter. This is helpful when I am dynamically pulling the objects name)

It just seems like a hassle when the "...ByExample" I feel should do this for you.

    This topic has been closed for replies.

    1 reply

    BKBK
    Community Expert
    Community Expert
    March 20, 2016

    Sir_Meili wrote:

    ArtIDtitleArtID
    1 The Water Lily Pond 1
    2 Woman with a Parasol 1
    3 Poppies 1
    4 The Night Watch 2
    5 The Jewish Bride 2

    artSearch = EntityLoadByExample( 'Art' , myBlankArt );

    Two comments:

    1.      The last table column should be artistID.
    2.       Why don't you just go for something like

                   artSearch = EntityLoadByExample(myBlankArt);

    Sir_MeiliAuthor
    Inspiring
    March 21, 2016

    1. You are correct. it shoudl be artistID (And it would be in my use case). I can't edit the original post to fix it.

    2. That is what I do, again you are correct. I'm new lot using EntityLoadByExample. It does not need the object name.

    So, to be clear, when I run:

    artSearch = EntityLoadByExample(myBlankArt);


    it completely ignores that the myBlankArt Object has the artist object in it and returns all art objects.




    (sorry for the errors in my example above, I was writing the example in the post, my objects are a bit more complex, so I wanted to dumb it down some.)

    BKBK
    Community Expert
    Community Expert
    March 27, 2016

    myBlankArt = EntityNew( 'Art' , { Artist = monet } );

    I would, after changing the last column name to artistID, do what comes naturally:

    myBlankArt = EntityNew( 'Art' , { artistID = 1 } );