Is Lazy Loading working?

62 views
Skip to first unread message

Andrew Scott

unread,
Dec 14, 2009, 4:35:26 AM12/14/09
to cf-or...@googlegroups.com

I don’t use cfdump that much, and prefer to use the debugger to look at the variables.

 

In this case the variable holds nothing more than the string representation of the array of objects.

 

So I decided to cfdump the object, but the question is that even though on the one-to-many I have lazy loading is true. It still dumps the records from the relationship.

 

So my question is this, is there a way to determine if lazy loading is working? And if it is and the cfdump pulls the records in, should the cfdump be a bit smarter here?

Tony Nelson

unread,
Dec 14, 2009, 11:51:09 AM12/14/09
to cf-orm-dev
I believe cfdump pulls in everything it can, essentially ignoring lazy
loading.

You could always set this.ormSettings.logSQL=true and look at the
queries that Hibernate is executing for your request.

-Tony

Bob Silverberg

unread,
Dec 14, 2009, 11:59:52 AM12/14/09
to cf-or...@googlegroups.com
I believe that Tony is correct; cfdump will ignore lazy loading.  If you want to "test" to see if your configuration does result in lazy loading, you could try this:

1. During a request, grab an object with a lazy loaded relationship, and store it in the session scope. *Do not* call the getter for the relationship property during this request.
2. On the next request, retrieve the object from the session scope, and attempt to retrieve the composed object via its getter.

You should get an error during step 2 if the composed object was not loaded during step 1 (which is what you would expect if it is supposed to be lazy loaded).

Cheers,
Bob


--

You received this message because you are subscribed to the Google Groups "cf-orm-dev" group.
To post to this group, send email to cf-or...@googlegroups.com.
To unsubscribe from this group, send email to cf-orm-dev+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cf-orm-dev?hl=en.





--
Bob Silverberg
www.silverwareconsulting.com

Brian Kotek

unread,
Dec 14, 2009, 12:03:04 PM12/14/09
to cf-or...@googlegroups.com
The easy way is to just look at the generated SQL that has been run. It's a good habit to get into anyway, since you want to do occasional sanity checks on the SQL being executed to make sure that something looks to be working on the surface, but under the hood is doing something crazy or running a lot of unnecessary SQL that indicates the setup being used isn't ideal.

--

Kerr

unread,
Dec 14, 2009, 12:48:36 PM12/14/09
to cf-orm-dev
I've experienced that <cfdump> ignores lazy loading as well, instead
gathering and dumping the entire object in question.

On Dec 14, 11:03 am, Brian Kotek <brian...@gmail.com> wrote:
> The easy way is to just look at the generated SQL that has been run. It's a
> good habit to get into anyway, since you want to do occasional sanity checks
> on the SQL being executed to make sure that something looks to be working on
> the surface, but under the hood is doing something crazy or running a lot of
> unnecessary SQL that indicates the setup being used isn't ideal.
>
> On Mon, Dec 14, 2009 at 4:35 AM, Andrew Scott <andr...@andyscott.id.au>wrote:
>
> >  I don’t use cfdump that much, and prefer to use the debugger to look at
> > the variables.
>
> > In this case the variable holds nothing more than the string representation
> > of the array of objects.
>
> > So I decided to cfdump the object, but the question is that even though on
> > the one-to-many I have lazy loading is true. It still dumps the records from
> > the relationship.
>
> > So my question is this, is there a way to determine if lazy loading is
> > working? And if it is and the cfdump pulls the records in, should the cfdump
> > be a bit smarter here?
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "cf-orm-dev" group.
> > To post to this group, send email to cf-or...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > cf-orm-dev+...@googlegroups.com<cf-orm-dev%2Bunsu...@googlegroups.com>
> > .

Brian Kotek

unread,
Dec 14, 2009, 1:05:19 PM12/14/09
to cf-or...@googlegroups.com
Of course. CFDump just recurses the object graph for whatever you give it. When it invokes the lazy properties, they are loaded.

There is actually no easy way to determine if you're dealing with a lazy collection that is not populated. That's the whole point: nothing should know you're using Hibernate. To external objects, the collection should always APPEAR to be populated. The fact that it is lazy and will only be loaded when it is actually referenced is meant to be completely hidden.

That said, there ARE ways (in Java) to determine this. But I have to ask, why would someone feel the need to know this on the CF side?

Devin Holloway

unread,
Dec 14, 2009, 2:24:55 PM12/14/09
to cf-or...@googlegroups.com

To quote from one of Rupesh's comments on his blog:

"That is one way. You can read the logged sql and see if the sql to load the lazy objects are being called. But thats not such a nice way.
Another way is to use the event handler - You can enable the event handler and write the preLoad methods in the related class. When you just load the object without accessing the lazy properties, if the preLoad() method gets called for the related objects, it would mean that the related object is getting loaded immediately and lazy is not working."

http://www.rupeshk.org/blog/index.php/2009/07/coldfusion-orm-troubleshooting-lazy-does-not-work/



 


I believe that Tony is correct; cfdump will ignore lazy loading.  If you want to "test" to see if your configuration does result in lazy loading, you could try this:

1. During a request, grab an object with a lazy loaded relationship, and store it in the session scope. *Do not* call the getter for the relationship property during this request.
2. On the next request, retrieve the object from the session scope, and attempt to retrieve the composed object via its getter.

You should get an error during step 2 if the composed object was not loaded during step 1 (which is what you would expect if it is supposed to be lazy loaded).

Cheers,
Bob
On Mon, Dec 14, 2009 at 11:51 AM, Tony Nelson <tonyne...@gmail.com> wrote:
I believe cfdump pulls in everything it can, essentially ignoring lazy
loading.

You could always set this.ormSettings.logSQL=true and look at the
queries that Hibernate is executing for your request.

-Tony

On Dec 14, 3:35 am, "Andrew Scott" <andr...@andyscott.id.au> wrote:
> I don't use cfdump that much, and prefer to use the debugger to look at the
> variables.
>
> In this case the variable holds nothing more than the string representation
> of the array of objects.
>
> So I decided to cfdump the object, but the question is that even though on
> the one-to-many I have lazy loading is true. It still dumps the records from
> the relationship.
>
> So my question is this, is there a way to determine if lazy loading is
> working? And if it is and the cfdump pulls the records in, should the cfdump
> be a bit smarter here?

--

You received this message because you are subscribed to the Google Groups "cf-orm-dev" group.
To post to this group, send email to cf-or...@googlegroups.com.
To unsubscribe from this group, send email to cf-orm-dev+...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/cf-orm-dev?hl=en.





--
Bob Silverberg
www.silverwareconsulting.com

 

--

You received this message because you are subscribed to the Google Groups "cf-orm-dev" group.
To post to this group, send email to cf-or...@googlegroups.com.
To unsubscribe from this group, send email to cf-orm-dev+...@googlegroups.com.

Andrew Scott

unread,
Dec 15, 2009, 3:50:03 AM12/15/09
to cf-or...@googlegroups.com
Thanks everyone, however I have a problem with the implementation and I
guess only adobe can answer this one.

In my eyes, if I have done a load on the object and I have lazy loading set
to true. The object when dumped really should not be calling getters to go
and grab the rest, after it is sitting in memory right?

It seems like it wasn't really thought out or there is another issue in play
here.

I just don't see how an object already sitting in memory, has to then go and
call the getter to grab related objects.

I appreciate every ones comments and suggestions and I think the preload is
a hack but a workable one.

It would also be nice if ColdFusion and the CFB team made the debugger
better suited in situations like this too, instead of a string
representation of the object. I raised a E/R in CFB, and it is under review
so it might not make CFB 1.0 but it might make CFB 1.5/2.0 hopefully.



Ashar

unread,
Dec 15, 2009, 7:16:57 AM12/15/09
to cf-orm-dev
I'm no expert on ORM but after a lot of head-banging and testing I
think I can
answer your last post.

...."In my eyes, if I have done a load on the object and I have lazy
loading set
to true. The object when dumped really should not be calling getters
to go
and grab the rest, after it is sitting in memory right? "...

Actually with lazy set to 'true' its just the opposite, and these are
two separate issues... 1) The object calling getters, and 2) The
properties being lazy loaded.
If you have lazy loading set to true, you are telling the object that
it 'does' need to go back and get the value of the property when the
getter is called.

Example... if you have a family taking a trip and you tell the car to
"lazy load" the children... the parents will be put in the car
with just "seats held available" for the children. When you tell the
car to dump its contents, the car will go back to the house,
get the lazy children and then show you the whole family. If you
had set lazy loading to false, then the children would have been put
in the car with the parents when it first
left the house and when you tell the car to dump its contents, it
will again show you the whole family.

..."I just don't see how an object already sitting in memory, has to
then go and
call the getter to grab related objects."...

"Dumping" calls the getters for every property in the object, period,
regardless of the lazy setting.

Lazy loading setting doesn't control whether the getters are called,
it just tells the getter what to do when it is called....
whether it should already be in the object and retrieve the value from
within the object (lazy false), or whether the getter needs to
go back to the source and get the value because it was not loaded
(lazy true).

If you are really trying to "test it" and verify that something is
loaded or is not loaded with your lazy setting,
the best option is to do what Bob said and store your object in
regular session in one request. Storing it in
local session will cut the object off from the road leading back to
the source. Then in
the next request dump the object held in the session variable. If you
have lazy set to true for a property then
when you dump the object you should get an error with something like
"could not initialize proxy, no session"
because the object can't get back to the source to get the lazy
properties.
With lazy set to false, when you dump the object you should not get
the error.

Ashar

Andrew Scott

unread,
Dec 15, 2009, 7:49:28 AM12/15/09
to cf-or...@googlegroups.com
I am aware that this is the reason behind its current behaviour, after
developing systems and applications for near 30 years. My Question is why!!

It is in memory, and it doesn't need to know about the getters and setters.
Period.

Raymond Camden

unread,
Dec 15, 2009, 7:53:02 AM12/15/09
to cf-or...@googlegroups.com
How is cfdump supposed to work then? The data is -behind- the object.
The only API the dump tag would see is the getter functions.

Andrew Scott

unread,
Dec 15, 2009, 8:46:19 AM12/15/09
to cf-or...@googlegroups.com
Ray,

I am currently looking further into this but what I have discovered so far
is surprising to the say the least. If Adobe says they can't do it I say
they can.



-----Original Message-----
From: cf-or...@googlegroups.com [mailto:cf-or...@googlegroups.com] On
Behalf Of Raymond Camden
Sent: Tuesday, 15 December 2009 11:53 PM
To: cf-or...@googlegroups.com
Subject: Re: Is Lazy Loading working?

A. M.

unread,
Dec 15, 2009, 9:01:49 AM12/15/09
to cf-or...@googlegroups.com
WOW !
Yeah, I've been developing apps for almost 30 years too....
But obviously I'm not the only person who doesn' t know everything.

Ashar

Raymond Camden

unread,
Dec 15, 2009, 9:08:01 AM12/15/09
to cf-or...@googlegroups.com
Heh, I think you are mistaken, but I hope you prove me wrong! :)

Andrew Scott

unread,
Dec 15, 2009, 9:33:01 AM12/15/09
to cf-or...@googlegroups.com
Ray,

Proof of concept is done, now I just need you to approve the riaforge.org
project I created.

Raymond Camden

unread,
Dec 15, 2009, 9:34:59 AM12/15/09
to cf-or...@googlegroups.com
I already did.

Andrew Scott

unread,
Dec 15, 2009, 9:37:32 AM12/15/09
to cf-or...@googlegroups.com
Ok, this is a very quick and dirty proof of concept.

http://Entitydump.riaforge.org/

So why can't Adobe have done this?



-----Original Message-----
From: cf-or...@googlegroups.com [mailto:cf-or...@googlegroups.com] On
Behalf Of Raymond Camden
Sent: Wednesday, 16 December 2009 1:08 AM

Brian Kotek

unread,
Dec 15, 2009, 9:43:00 AM12/15/09
to cf-or...@googlegroups.com
Andrew, why do you care? You've already been given several options to determine how the lazy loading is working. Looking at the generated SQL is the common way this is done, and has the bonus of making you keep an eye on what is happening and looking for issues in your ORM configuration that are triggering inefficient or unnecessary SQL. What EXACTLY are you expecting? Dump elements of type HibernateProxy? An extra cfdump attribute for "includeLazy="true|false"? Empty CF arrays/structs?

Of COURSE it is probably possible. But it would be difficult. The cfdump tag is, essentially, a CFML custom tag. It can't check the data type of native Java objects via IsInstanceOf unless they are created using CreateObject, which these are not. And even if it could, there is no easy or efficient way to determine the underlying Java collection type (or the type of its elements) from CFML. What you're asking for would require extensive work, reimplementing cfdump in Java and jumping through all sorts of hoops to bridge the CF objects and the Java objects so that the output remains consistent.

Is it possible? Probably. Is it feasible? Very doubtful. Since there are FAR easier ways to track lazy loading, I can't imagine any possible reason Adobe would devote all this effort to do this. Just look at the SQL and move on.

Andrew Scott

unread,
Dec 15, 2009, 9:46:33 AM12/15/09
to cf-or...@googlegroups.com

Shows you how much you really know Brian!!

 

http://entitydump.riaforge.org/

 

 

 

From: cf-or...@googlegroups.com [mailto:cf-or...@googlegroups.com] On Behalf Of Brian Kotek
Sent: Wednesday, 16 December 2009 1:43 AM
To: cf-or...@googlegroups.com
Subject: Re: Is Lazy Loading working?

 

Andrew, why do you care? You've already been given several options to determine how the lazy loading is working. Looking at the generated SQL is the common way this is done, and has the bonus of making you keep an eye on what is happening and looking for issues in your ORM configuration that are triggering inefficient or unnecessary SQL. What EXACTLY are you expecting? Dump elements of type HibernateProxy? An extra cfdump attribute for "includeLazy="true|false"? Empty CF arrays/structs?

Brian Kotek

unread,
Dec 15, 2009, 9:48:01 AM12/15/09
to cf-or...@googlegroups.com
I might be missing something, but what you've done here:

if(structKeyExists(arguments.data[count], 'lazy')) {
                propertyValue = 'Object not loaded';
            } else {
                propertyValue = evaluate("arguments.object.get#arguments.data[count].name#()");
            }

isn't doing anything. All this does is assume that if the property is marked as lazy, it is not loaded. That's completely absurd. This doesn't tell you whether the lazy association has been loaded, all it tells you is if the property has the lazy attribute set to true.


Brian Kotek

unread,
Dec 15, 2009, 10:01:49 AM12/15/09
to cf-or...@googlegroups.com
Congratulations, genius. You wrote a tag that can read property metadata. Have fun with that in a situation like this:

user = EntityLoad( 'User', 1 );
userRoles = user.getUserRoles();
EntityDump( user );

Hey look, the dump shows that my lazy user roles weren't loaded because my userRoles property has lazy="true". Except....they WERE loaded. Hmmm.

Andrew Scott

unread,
Dec 15, 2009, 10:07:56 AM12/15/09
to cf-or...@googlegroups.com

Brian,

 

There are still a few things I need to work on, the point is that this information is held in memory and I am working of public methods to the object. But as a proof of concept Adobe can check to see if the property holds a value or not, and also check to see if it is marked lazy =true and ignore the call to get the data.

 

My point still stands that if I can do it with limited methods available to me, what could I do if I had the underlying private methods and or source to do a better job?

 

So my point still stands, why can’t adobe do something similar with the object if it is held in memory?

 

 

From: cf-or...@googlegroups.com [mailto:cf-or...@googlegroups.com] On Behalf Of Brian Kotek
Sent: Wednesday, 16 December 2009 2:02 AM
To: cf-or...@googlegroups.com
Subject: Re: Is Lazy Loading working?

 

Congratulations, genius. You wrote a tag that can read property metadata. Have fun with that in a situation like this:

Brian Kotek

unread,
Dec 15, 2009, 10:22:53 AM12/15/09
to cf-or...@googlegroups.com
What you're doing here doesn't tell you anything about whether the lazy association was ACTUALLY LOADED. The only way to tell whether the collection is actually a PersistentCollection, or whether one or more of the elements within the collection are actually HibernateProxies (or whatever Java class Adobe has created to represent proxied CFC instances), is to do this at the Java level. At a far lower-level than the CFDUMP tag lives at. Which is what I tried to explain to you earlier, before you told how dumb I am.

Scott Stroz

unread,
Dec 15, 2009, 10:23:20 AM12/15/09
to cf-or...@googlegroups.com
Please forgive me if this is a stupid question, but, aren't all
objects 'held in memory' when they are created? Granted, some may be
'destroyed' sooner than others, but they still reside 'in memory' for
a brief time.


> So my point still stands, why can’t adobe do something similar with the
> object if it is held in memory?

--
Scott Stroz
---------------
The DOM is retarded.

http://xkcd.com/386/
Reply all
Reply to author
Forward
0 new messages