Sure is a bug but of the logger. We shouldn't call ToString on a dyn-proxy if we don't want explicitly a call to the underlining instance. For log matters on a proxy we should show : *entityname#id* We are using *entityname#id "*pattern" in others places (for exception at least IIRC).
On Thu, Aug 11, 2011 at 7:52 PM, Ayende Rahien <[email protected]> wrote: > Fabio, > The actual problem happens when you are have logging enabled. > The reason for that is at > NHibernate.Loader.Criteria.CriteriaQueryTranslator.CreateCriteriaSQLAliasMap() > We log the parameter value there, which obviously calls ToString() on it. > Because of the behavior of the new proxy factory, it forces lazy loading of > that parameter. > I would argue that this is a bug, since logging should not cause additional > calls to the DB. > > On Thu, Aug 11, 2011 at 3:43 PM, Fabio Maulo <[email protected]> wrote: > >> The problem is not how ToString is intercepted but the call to ToString >> itself. >> A proxy have to be initialized to all methods excepting get_Id (to be >> short). >> I don't think we are calling ToString other than some special logging is >> called and the log is enabled. >> >> Repeted: the problem is not the proxy behavior but the log behavior (the >> SQL logger call ToString to show the parameter value but the parameter >> should not be a proxy, just the value used for the query). >> >> btw: in your query, if you check for the Id directly instead use >> session.Load your "problem" will disappear. >> >> >> On Thu, Aug 11, 2011 at 4:26 PM, Joseph Daigle >> <[email protected]>wrote: >> >>> Done: https://nhibernate.jira.com/browse/NH-2834 >>> >>> In doing more research I actually discovered this "bug" is really the >>> result of relying on Castle's behavior when handling proxies. Prior to 3.1 >>> LinFu actually behaves the same way that the new DefaultProxyFactory in 3.2 >>> behaves; in that it intercepts calls to ToString() sent to the base object >>> class and forces the proxy to initialize. >>> >>> I personally think that the proxy should only be initialized for >>> ToString() methods if the mapped class overrides ToString(), much in the >>> same way the Equals() and GetHashCode() behave. So I submitted a patch which >>> introduces that same behavior. If ToString() is not overridden on the proxy, >>> then simply return the class name. Otherwise fall through the default >>> behavior for initializing the proxy. >>> >>> ToString() is one of those methods which is very easy to call without >>> explicitly calling it. Passing an object into code that, for example, >>> generates exception messages or logs will likely call ToString() somewhere, >>> which can have unintended side-effects. Such as an extra database query. >>> >>> -- >>> Joseph Daigle >>> >> >> >> >> -- >> Fabio Maulo >> >> > -- Fabio Maulo
