Difference between lazy="proxy|no-proxy"

1,845 views
Skip to first unread message

belva...@googlemail.com

unread,
May 19, 2011, 3:24:48 PM5/19/11
to nhu...@googlegroups.com
Hi,

i just try to optimize my app a little and there are some things i don't understand.
Usually i mark all <many-to-one> associations with fetch="join", so all associations
are loaded in one step, if i use Session.Get(). Using Linq, this is ignored and i
have to use Session.Query<>().Fetch( t => t.Category ) etc. All associations
not included in the Fetch() call will be loaded separatly step by step, when calling
ToList(). So far i understand the behaviour. There are some associations
i will only need in rare cases. So i thought it would be nice to load them only when
accessed for the first time.
As far as i understood lazy="proxy|no-proxy" will do this. According to this

http://ayende.com/blog/4378/nhibernate-new-feature-no-proxy-associations

an association marked as lazy=no-proxy" will only be loaded if accessed for
the first time but will be created with the ID property set. If i use

<many-to-one name="TMScript" column="SCRIPT_ID" class="Domain.Base.Scripting.Script" lazy="no-proxy"/>

it does nothing but creating a proxy of a Script entity and querying it's values from the DB in a separate
query.

If i use

<many-to-one name="TMScript" column="SCRIPT_ID" class="Domain.Base.Scripting.Script" lazy="proxy"/>

it works they way i wanted it.
So, can anyone please explain what the difference betwen lazy="proxy" and lazy ="no-proxy" is?

Thanks

Fabio Maulo

unread,
May 19, 2011, 6:19:31 PM5/19/11
to nhu...@googlegroups.com
the level of the proxy

belva...@googlemail.com

unread,
May 19, 2011, 6:40:05 PM5/19/11
to nhu...@googlegroups.com
Hm i think i understand this. But shouldn't the behaviour be the same? Why "no-proxy" immediately queries
to the database?

Am schrieb Fabio Maulo <fabio...@gmail.com>:
> the level of the proxy
>
>
>
>
> --
>
> You received this message because you are subscribed to the Google Groups "nhusers" group.
>
> To post to this group, send email to nhu...@googlegroups.com.
>
> To unsubscribe from this group, send email to nhusers+u...@googlegroups.com.
>
>
> For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.
>
>
>
>

Ramon Smits

unread,
May 20, 2011, 3:08:52 AM5/20/11
to nhu...@googlegroups.com
Hm i think i understand this. But shouldn't the behaviour be the same? Why "no-proxy" immediately queries
to the database?

As a proxy makes it possible to have delayed loading?


Mohamed Meligy

unread,
May 20, 2011, 5:03:30 AM5/20/11
to nhu...@googlegroups.com
Ramon, this is not eager loading.

Quoting from the mentioned post:

When lazy is set to no-proxy, the following things happen:
  • The association is still lazy loaded (note that in older versions of NHibernate, setting it to no-proxy would trigger eager loading, this is no longer the case).
  • The first time that you access the property the value will be loaded from the database, and the actual type will be returned.

@belvasis,
How are checking this? Note that maybe even looking up the value in debugger or Visual Studio Watch window triggers this. Are you sure your code is not touching the property in any way?
Can you isolate it and paste it in a letter message?

Thanks a lot.

Regards,

 

Mohamed Meligy
Readify | Senior Developer

M:+61 451 835006 | W: readify.net

Description: Description: Description: Description: rss_16  Description: Description: Description: Description: cid:image003.png@01CAF81D.6A076510  Description: Description: Description: Description: cid:image005.png@01CAF81D.6A076510



belva...@googlemail.com

unread,
May 20, 2011, 5:34:43 AM5/20/11
to nhu...@googlegroups.com
@mohamed

to test this, i simply do

Marker pTM = Session.Get(10824);

and then check the sql output to the console. Using "proxy" only one query is executed:

NHibernate: SELECT marker0_.MARKER_ID as REPORTS1_282_2_...

The query for the Script is then executed if i look at the property in the VS watch window.

Using "no-proxy" the call to Get shows two executed queries, one for the Marker itself and the second for the Script:

NHibernate: SELECT marker0_.MARKER_ID as REPORTS1_282_2_...
NHibernate: SELECT script0_.SCRIPT_ID as T1_264_3_, script0_.SC_DESCR ...

One guess was that the ID is the problem since this is a property and it will be touched to create the temp
instance. So i changed it to access="field.pascalcase-m-underscore" but it did'nt solve the problem.

Am schrieb Mohamed Meligy <eng.m...@gmail.com>:

> Ramon, this is not eager loading.
>
> Quoting from the mentioned post:
>
>
>
>
> When lazy is set to no-proxy, the following things happen:The association is still lazy loaded (note that in older versions of NHibernate, setting it to no-proxy would trigger eager loading, this is no longer the case).
>
> The first time that you access the property the value will be loaded from the database, and the actual type will be returned.
>
> @belvasis,
> How are checking this? Note that maybe even looking up the value in debugger or Visual Studio Watch window triggers this. Are you sure your code is not touching the property in any way?
>
>
> Can you isolate it and paste it in a letter message?
>
>
> Thanks a lot.
>
>
> Regards,
>  
>
> Mohamed Meligy
> Readify | Senior Developer
>
> M:+61 451 835006 | W: readify.net
>
>
>     
>
>
>
>
>
>
>
>
>
>

Mohamed Meligy

unread,
May 20, 2011, 5:59:11 AM5/20/11
to nhu...@googlegroups.com
The query for the Script is then executed if i look at the property in the VS watch window. 
Maybe this is the reason? To get the property value, even in Visual Studio watch window, the property getter is executed.

 

Mohamed Meligy
Readify | Senior Developer

M:+61 451 835006 | W: readify.net

Description: Description: Description: Description: rss_16  Description: Description: Description: Description: cid:image003.png@01CAF81D.6A076510  Description: Description: Description: Description: cid:image005.png@01CAF81D.6A076510

belva...@googlemail.com

unread,
May 20, 2011, 6:12:12 AM5/20/11
to nhu...@googlegroups.com
I don't think so beacuse in the first case ("proxy") => one query is executed
in the second case ("no-proxy") => two queries are executed immediately

In the first case, the second query (for the Script property) is only executed, if i use the VS watch window
or something. This is the expected behaviour. But i thought this should be the same if i use "no-proxy"


Am schrieb Mohamed Meligy <eng.m...@gmail.com>:
>
>
>
>
>
>
>
>
>
>
>
>

H.Alex

unread,
May 20, 2011, 1:00:39 PM5/20/11
to nhusers
you can try testing with

NHibernateUtil.IsInitialized(laizy property);


On May 20, 12:12 pm, belvasis...@googlemail.com wrote:
> I don't think so beacuse in the first case ("proxy") => one query is  
> executed
> in the second case ("no-proxy") => two queries are executed immediately
>
> In the first case, the second query (for the Script property) is only  
> executed, if i use the VS watch window
> or something. This is the expected behaviour. But i thought this should be  
> the same if i use "no-proxy"
>
> Am schrieb Mohamed Meligy <eng.mel...@gmail.com>:
>
>
>
>
>
>
>
> > The query for the Script is then executed if i look at the property in  
> > the VS watch window.
> > Maybe this is the reason? To get the property value, even in Visual  
> > Studio watch window, the property getter is executed.
> > Mohamed Meligy
> > Readify | Senior Developer
> > M:+61 451 835006 | W: readify.net
> > On Fri, May 20, 2011 at 7:34 PM, belvasis...@googlemail.com> wrote:
> > @mohamed
> > to test this, i simply do
> > Marker pTM = Session.Get(10824);
> > and then check the sql output to the console. Using "proxy" only one  
> > query is executed:
> > NHibernate: SELECT marker0_.MARKER_ID as REPORTS1_282_2_...
> > The query for the Script is then executed if i look at the property in  
> > the VS watch window.
> > Using "no-proxy" the call to Get shows two executed queries, one for the  
> > Marker itself and the second for the Script:
> > NHibernate: SELECT marker0_.MARKER_ID as REPORTS1_282_2_...
> > NHibernate: SELECT script0_.SCRIPT_ID as T1_264_3_, script0_.SC_DESCR ...
> > One guess was that the ID is the problem since this is a property and it  
> > will be touched to create the temp
> > instance. So i changed it to access="field.pascalcase-m-underscore" but  
> > it did'nt solve the problem.
> > Am schrieb Mohamed Meligy eng.mel...@gmail.com>:
> > > Ramon, this is not eager loading.
>
> > > Quoting from the mentioned post:
>
> > > When lazy is set to no-proxy, the following things happen:The  
> > association is still lazy loaded (note that in older versions of  
> > NHibernate, setting it to no-proxy would trigger eager loading, this is  
> > no longer the case).
>
> > > The first time that you access the property the value will be loaded  
> > from the database, and the actual type will be returned.
>
> > > @belvasis,
> > > How are checking this? Note that maybe even looking up the value in  
> > debugger or Visual Studio Watch window triggers this. Are you sure your  
> > code is not touching the property in any way?
>
> > > Can you isolate it and paste it in a letter message?
>
> > > Thanks a lot.
>
> > > Regards,
>
> > > Mohamed Meligy
> > > Readify | Senior Developer
>
> > > M:+61 451 835006 | W: readify.net
>
> > > On Fri, May 20, 2011 at 5:08 PM, Ramon Smits ramon.sm...@gmail.com>  

belva...@googlemail.com

unread,
May 20, 2011, 1:27:01 PM5/20/11
to nhu...@googlegroups.com
If I use "no-proxy" it should (and is) always be initialized, but it should not be loaded immedetialy from the DB (i think).
This is not a real issue for me right now, since what i wanted can be accomplished using lazy="proxy", but i 'm really interested
in what the problem here is or what i'm doing wrong.


Am schrieb "H.Alex" <h.al...@gmail.com>:

Mohamed Meligy

unread,
May 20, 2011, 1:36:41 PM5/20/11
to nhu...@googlegroups.com
I have done some test now.
Yeah, it "does" load the reference if you set lazy="no-proxy" although the article says otherwise!!

 

Mohamed Meligy
Readify | Senior Developer

M:+61 451 835006 | W: readify.net

Description: Description: Description: Description: rss_16  Description: Description: Description: Description: cid:image003.png@01CAF81D.6A076510  Description: Description: Description: Description: cid:image005.png@01CAF81D.6A076510

Ricardo Peres

unread,
May 20, 2011, 2:07:42 PM5/20/11
to nhusers
Is your entity marked as lazy?
If not, the only thing that can be lazy loaded (or proxied, if you
prefer) is one to many collections.


On May 20, 6:36 pm, Mohamed Meligy <eng.mel...@gmail.com> wrote:
> I have done some test now.
> Yeah, it "does" load the reference if you set lazy="no-proxy" although the
> article says otherwise!!
> Are your entities marked as lazy
> *Mohamed Meligy
> *Readify | Senior Developer
>
> M:+61 451 835006 | W: readify.net
> [image: Description: Description: Description: Description:
> rss_16]<http://gurustop.net>
> [image: Description: Description: Description: Description:
> cid:image003....@01CAF81D.6A076510]
> <http://www.linkedin.com/in/meligy>  [image:
> Description: Description: Description: Description:
> cid:image005....@01CAF81D.6A076510] <http://twitter.com/meligy>
>  <http://www.greatplacetowork.com.au/best/best-companies-australia.php><http://www.readify.net/AboutUs/NewsItem.aspx?id=10>
>
>
>
>
>
>
>
> On Sat, May 21, 2011 at 3:27 AM, <belvasis...@googlemail.com> wrote:
> > If I use "no-proxy" it should (and is) always be initialized, but it should
> > not be loaded immedetialy from the DB (i think).
> > This is not a real issue for me right now, since what i wanted can be
> > accomplished using lazy="proxy", but i 'm really interested
> > in what the problem here is or what i'm doing wrong.
>
> > Am schrieb "H.Alex" <h.ale...@gmail.com>:

Mohamed Meligy

unread,
May 20, 2011, 2:09:59 PM5/20/11
to nhu...@googlegroups.com
Interesting, so, this setting although does work / validate on many to one properties, is essentially useless for these?

 

Mohamed Meligy
Readify | Senior Developer

M:+61 451 835006 | W: readify.net

Description: Description: Description: Description: rss_16  Description: Description: Description: Description: cid:image003.png@01CAF81D.6A076510  Description: Description: Description: Description: cid:image005.png@01CAF81D.6A076510

Ricardo Peres

unread,
May 20, 2011, 2:25:53 PM5/20/11
to nhusers
There are three types of proxies:

1 - Proxies to many-to-one entities (such as MyOtherEntity);
2 - Proxies to properties (such as String);
3 - Proxies to collections (such as ISet<MyOtherEntity>.

For the first two, you need the containing entity type to be marked as
lazy; this way, NHibernate will create a proxy for the entity type
(creating a class that inherits from it), and will replace those
properties marked as lazy (types 1 and 2), which have to be virtual,
with code that will only load them on demand, that is, when they are
first accessed. Marking a property of type 1 or 2 in a non-lazy entity
type will do exactly nothing.

RP


On May 20, 7:09 pm, Mohamed Meligy <eng.mel...@gmail.com> wrote:
> Interesting, so, this setting although does work / validate on many to one
> properties, is essentially useless for these?
>

belva...@googlemail.com

unread,
May 21, 2011, 3:41:37 PM5/21/11
to nhu...@googlegroups.com
So it will stay a mystery, at least for me, because I don't know what else i should say or describe.

The containing entity is a proxy:

Marker pTM = Session.Get(10847)

=> pTM.GetType().ToString() => "Castle.Proxies.MarkerProxy"

and again
using lazy="proxy" for the many-to-one property NH loads it on demand (when first accessed)
using lazy="no-proxy" for the many-to-one property NH loads it immediately (before it is accessed for the first time)



Am schrieb Ricardo Peres <rjp...@gmail.com>:

> There are three types of proxies:
>
>
>
> 1 - Proxies to many-to-one entities (such as MyOtherEntity);
>
> 2 - Proxies to properties (such as String);
>
> 3 - Proxies to collections (such as ISet.

Fabio Maulo

unread,
May 21, 2011, 6:15:48 PM5/21/11
to nhu...@googlegroups.com
the difference is the level of the proxy (as said at the begin).
class A
{
B Related{get;set;}
}

With B marked as proxy NH will assign the property 'Related' with a proxy
With B marked as no-proxy NH will proxy the instance of class A and when you will try to access to the property 'Related' it will it the DB and will give you an instance of type B (not a proxy).

Fabio Maulo

unread,
May 21, 2011, 6:23:07 PM5/21/11
to nhu...@googlegroups.com
ah... another matter...
the behavior I'm talking about is since NH3.0.0
with previous versions lazy="no-proxy" and lazy="false" is exactly the same

belva...@googlemail.com

unread,
May 21, 2011, 7:19:53 PM5/21/11
to nhu...@googlegroups.com
Fabio,

i understand all of this and it is exactly as you described it BUT it will hit the DB for the property 'Related' before i ever access it,
if it is marked as "no-proxy". The SQL output then shows two selects if i call Session.Get...one for A and one for Related (B).
This is the point i don't understand.
If B is marked as "proxy" then the output shows only one select and the second for Related is shown, if i access it for the first time.
Shouldn't the "DB hit" behaviour be the same for both markers?
I use version 3.0.


Am schrieb Fabio Maulo <fabio...@gmail.com>:
> the difference is the level of the proxy (as said at the begin).class A

> {
> B Related{get;set;}
> }
>
>
> With B marked as proxy NH will assign the property 'Related' with a proxy
> With B marked as no-proxy NH will proxy the instance of class A and when you will try to access to the property 'Related' it will it the DB and will give you an instance of type B (not a proxy).
>
>
>
>
>
>
Reply all
Reply to author
Forward
0 new messages