-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 
Author Message
 Post subject: Unmapped virtual property initializes proxy
PostPosted: Thu Feb 09, 2006 6:30 pm 
Expert
Expert

Joined: Fri Oct 28, 2005 5:38 pm
Posts: 390
Location: Cedarburg, WI
Hibernate version: 1.0.2

All of my classes are marked lazy=true, so I have mapped properties defined as virtual. No problem with that. However, if I also define an unmapped property as virtual, and access it on an uninitialized proxy instance, it causes the proxy to initialize itself. This seems wrong. The proxy generator should only override virtual properties that are actually mapped.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 10, 2006 4:08 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
But the generator doesn't know what the property accessors actually do. Even if it's not the case already, it may be that in a non-mapped property accessor you actually access other mapped properties of the object directly through fields, for example, so the object has to be initialized.

Is this a big problem for you? If not, I would ignore it because making it work 100% correctly would be complicated. And besides, you may change the non-mapped property later to do something that requires access to persistent properties.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 13, 2006 12:22 am 
Regular
Regular

Joined: Mon May 16, 2005 1:35 am
Posts: 67
It might be nice to have an attribute which can be added to any virtual method or property to prevent lazy initialisation.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 13, 2006 3:52 pm 
Expert
Expert

Joined: Fri Oct 28, 2005 5:38 pm
Posts: 390
Location: Cedarburg, WI
Sergey wrote:
Quote:
it may be that in a non-mapped property accessor you actually access other mapped properties of the object directly through fields


If people do that, that's their problem. I.e. if you create a lazy-loading entity, you can't expect that accessing the field directly anywhere outside of the property itself is going to behave correctly.

Since the proxy generator doesn't know anything about NHibernate mappings, and therefore must make the dangerous assumption that a virtual property is a mapped one, there should at least be an attribute that we can decorate a property with to indicate that it's not mapped, or not lazy-loadable. E.g.

Code:
[Lazy(false)]
public string MyNonMappedProperty
{
    get {...}
}
[/quote]


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 13, 2006 5:06 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Quote:
if you create a lazy-loading entity, you can't expect that accessing the field directly anywhere outside of the property itself is going to behave correctly.


Not really. If you make all your methods virtual, then accessing the field anywhere inside the class will work just fine.

The idea is not to intercept just the persistent property accessors, but to intercept any use of the object through one of its methods, and load it on demand.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 13, 2006 7:32 pm 
Expert
Expert

Joined: Fri Oct 28, 2005 5:38 pm
Posts: 390
Location: Cedarburg, WI
??? I thought the whole point of using properties (rather than fields) was to provide a central access point, for anything from lazy-loading to performing validation to raising "OnChange" events. If a class accesses its own data through its properties rather than fields, this will all work just fine. Expecting all access to be through the property, even from within the class itself, especially if the class is lazy-loaded, sounds perfectly reasonable. Anyway, from what I understand, most people generate their classes, and business logic goes elsewhere, so the private fields are inaccessible from where any methods would be written.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 15, 2006 7:29 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
I'm not saying your point of view (i.e that fields should only be accessed through properties, even inside the class) is wrong, just that it's not the only right one. And NH supports both this and the alternative style where fields may be accessed directly inside the object's methods.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 15, 2006 12:13 pm 
Expert
Expert

Joined: Fri Oct 28, 2005 5:38 pm
Posts: 390
Location: Cedarburg, WI
Hmmm... once lazy-loading is involved, directly accessing fields does seem to become a "wrong" approach, because then we're forced to make dubious assumptions, namely that any virtual property (and any virtual method?) could need lazy-loading to execute. This makes it impossible to define a virtual property or method that should not trigger lazy-loading. If data is accessed only through properties, then this limitation (mistaken assumption) does not exist.

Expecting people to access lazy-loaded data through properties, even from within the class itself, does not sound unreasonable at all, at least to me. Long before we started using NHibernate, we commonly had lazy-initializing properties, and it was generally understood in our shop that direct access of fields (outside the property itself) was a bad idea, since it not only breaks possible lazy-initialization, but forces the class to know that the property is trivially backed by a field. If the property getter becomes more complex, then all the places where it is directly accessed as a field need to be cleaned up, since they violated the class's contract in the first place. Good luck remembering that it was violated in the first place.

However, if you're worried about breaking people's existing code by changing the proxy to only wrap mapped properties, I can understand that. Still, supporting an attribute like [Lazy(false)] that could be applied to virtual properties and methods would seem to make everyone happy ...


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 16, 2006 11:25 pm 
Expert
Expert

Joined: Fri Oct 28, 2005 5:38 pm
Posts: 390
Location: Cedarburg, WI
Sergey, even if you intended to have all virtual properties and methods trigger lazy loading so that even field access will be safe, it won't work -- I just noticed that proxies keep their own storage for your property values. I.e. if I have a proxied entity, after the proxy is initialized, the properties show values, but my underlying fields are all still null! The proxy property getters/setters aren't calling the base property getters/setters!

This looks like a MAJOR problem, because we have logic (validation, PropertyChanging/PropertyChanged events, etc) that needs to be executed. The proxy property getters/setters can't simply replace the base ones -- they should lazy-load if needed, and then simply call the base.

I'll post this issue as its own thread ...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 17, 2006 4:20 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
Nels_P_Olsen wrote:
Hmmm... once lazy-loading is involved, directly accessing fields does seem to become a "wrong" approach, because then we're forced to make dubious assumptions, namely that any virtual property (and any virtual method?) could need lazy-loading to execute. This makes it impossible to define a virtual property or method that should not trigger lazy-loading. If data is accessed only through properties, then this limitation (mistaken assumption) does not exist.


The cuurent implementation in CVS seems to reuiqre that all public methods are virtual... So, it should guarantee that the You can not use the object without triggering lazy loading.

Actually, I like it. When writing classes, I do not want to know anything about lazy loading. I.e. to worry if class is already loaded or not. Well, I only have to remember to make all methods virtual...

Gert


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.