Many to one filters

261 views
Skip to first unread message

Ayende Rahien

unread,
Aug 14, 2009, 2:56:12 AM8/14/09
to nhibernate-development
Hi,
I run into an interesting problem.

Given the following

public class Category
{
public virtual int ID { get; private set; }
public virtual DateTime ValidUntil { get; set; }
}

public class Invoice
{
public virtual int ID { get; private set; }
        public virtual string OtherProp { get; set; }
public virtual Category Category { get; set; }
}

Category has a filter applied on it, assume that it is on and will filter the respective category.
NH 2.1 has a new feature that allows filters on many to one associations.
The problem is that we get different behaviors depending on the eager load settings that we have.

[Test]
public void LazyLoadAndEagerLoadShouldHaveSameResult()
{
using (ISession s = OpenSession())
{
s.EnableFilter("validity").SetParameter("date", pastTime);

var invoice = s.CreateCriteria<Invoice>()
.UniqueResult<Invoice>();
Assert.IsNotNull(invoice.Category);

s.Clear();

invoice = s.CreateCriteria<Invoice>()
.SetFetchMode("Category", FetchMode.Eager)
.UniqueResult<Invoice>();
Assert.IsNotNull(invoice.Category);
}
}

I think that this should be the same behavior in both, but it isn't.
Obviously, there are problems with either saying that this is going to be the same (we basically state that if we have filters enabled any many-to-one association to a filter entity becomes non lazy) or if we keep the current and inconsistent state.

Richard Brown (gmail)

unread,
Aug 14, 2009, 3:55:45 AM8/14/09
to nhibernate-development
Isn't it consistent to say that the filter will be applied if the table/entity appears in the query?
 
Although, I understand it looks a little cryptic, since the table might appear in the query due to a FetchMode (like your example), or a lazy="false" in the mapping (more subtle).

Richard Brown (gmail)

unread,
Aug 14, 2009, 4:40:25 AM8/14/09
to nhibernate-development
Wait, I didn't get that fully.  (Probably me be stupid)
 
If we query, and the query doesn't return the category, I expect the (lazy load) relation to filter it:
invoice.Category should be null (lazy load should filter it);
 
If we query, and the query does return it (eagerly), still expect the relation to be null:
invoice.Category should also be null (query should filter it);
 
Which isn't working?

Ayende Rahien

unread,
Aug 14, 2009, 5:23:13 AM8/14/09
to nhibernate-...@googlegroups.com
Richard,
It isn't working right now for a different reason, because we always put the condition in the where clause, not in the join condition.
I am talking about the actual design, not the impl. I consider the impl. buggy at the moment and will fix it soon.

As for the lazy load scenario, it doesn't work.

Imagine:

var invoice = s.Get<Invoice>(1); // select * from Invoices where Id = 1
Console.WriteLine(invoice.Category.Name); // select * from Categories where Id =2 and date > @validDate

Now, consider what the options are.
If we lazy load category, we don't know if it is valid or not.
Because we don't know, we put a proxy there for standard lazy loading.
Next, when we do load it, we are in a conundrum. We have what is effectively an invalid object.
NH doesn't let it happen, usually.

Moreover, if we used eager loading in the same scenario, it would throw Null Ref Error.

Richard Brown (gmail)

unread,
Aug 14, 2009, 5:25:29 AM8/14/09
to nhibernate-...@googlegroups.com
I get it.  I think you're right, it should eager-load to determine correct result.

Ayende Rahien

unread,
Aug 14, 2009, 5:40:44 AM8/14/09
to nhibernate-...@googlegroups.com
Problem is that eager loading is going to cause _nasty_ issues. 
Thing about the potential for Cartesian products, for example, or how much extra data we would have to load.

Richard Brown (gmail)

unread,
Aug 14, 2009, 7:05:47 AM8/14/09
to nhibernate-...@googlegroups.com
Is there a problem here (that is outside user control) because we implemented this feature implicitly?
 
With filters on classes, we add the filter inside the class mapping and this only affects queries but not Load/Get using an ID.
 
With many-to-one relationships (bag/set) we add an explicit filter, or the filter on the class is ignored (a collection without the filter gets everything regardless of the class filter).
 
With filter on many-to-one ... shouldn't we really make this explicit in the mapping?
 
e.g., something like:
 
<many-to-one name="Category" class="Category>
    <filter name="validity">ValidUntil > :date</filter>
</many-to-one>
 
which would make the queries (and loads) eager on that property when the filter is enabled?  (Or do we already do this - I couldn't find any test with an example like that)
 
(I'm just thinking out loud here - hopefully not talking rubbish)

Fabio Maulo

unread,
Aug 14, 2009, 8:41:05 AM8/14/09
to nhibernate-...@googlegroups.com
The concept of the filter is that it is applied when a query-space (table) is affected by the filter.
This should be the behaviour.

var invoice = s.CreateCriteria<Invoice>()
.UniqueResult<Invoice>();
and 
invoice = s.CreateCriteria<Invoice>()
.SetFetchMode("Category", FetchMode.Eager)
.UniqueResult<Invoice>();

are two different queries and the filter may cause different behaviour.
In this case the filter shouldn't be applied in the first query and should be applied in the second queries.
With HQL all is more clear:
from Invoice
and
from Invoice i join fetch i.Category

2009/8/14 Richard Brown (gmail) <fluk...@googlemail.com>



--
Fabio Maulo

Roger Kratz

unread,
Aug 14, 2009, 10:18:00 AM8/14/09
to nhibernate-...@googlegroups.com
Just 2 cents from a simple user...

Isn't it a bit strange with filters on many-to-one relationships? I know this comment might be a bit late but I'm still on 2.0 in live projects and haven't really given it any deeper thought until now.

Let's say you have a User entity. Other entities might have CreatedBy and/or UpdatedBy prop. When an User is unactivated a flag is set. NH:s filters have been perfect in this situation. If persons are queried for, unactive ones won't be returned - perfect. However if you want to know who created a certain entity you can (could?) always look at the prop and the unactive User is still there.
If I've understood it correctly, many-to-one now starts taking filters into consideration, the above will work only if the query in the first place was written in a certain way. Feels a bit strange to me.

Also, as a sidenote, isn't a bit strange replacing a filtered entity with null? I don't say it happens often or is a good practise but null _might_ have a business meaning that's not what a "filtered" entity was suppose to equal to.

If filters on many-to-one are needed, maybe have it declared on the <many-to-one> tag instead? From what I've understood it, it takes the "class filters" into consideration.

Finally, I might have missed something. I'm sure you have really good reasons for this breaking change, I just haven't really not got it yet. Also, I'm on a looong vacation here and haven't tried this part of NH in 2.1 - I could very much talking rubbish here if I've totally missed how it works reading this (and other) forum discussions.

Keep up the good work
Roger

________________________________
Från: nhibernate-...@googlegroups.com [nhibernate-...@googlegroups.com] för Fabio Maulo [fabio...@gmail.com]
Skickat: den 14 augusti 2009 14:41
Till: nhibernate-...@googlegroups.com
Ämne: [nhibernate-development] Re: Many to one filters

The concept of the filter is that it is applied when a query-space (table) is affected by the filter.
This should be the behaviour.

var invoice = s.CreateCriteria<Invoice>()
.UniqueResult<Invoice>();
and
invoice = s.CreateCriteria<Invoice>()
.SetFetchMode("Category", FetchMode.Eager)
.UniqueResult<Invoice>();

are two different queries and the filter may cause different behaviour.
In this case the filter shouldn't be applied in the first query and should be applied in the second queries.
With HQL all is more clear:
from Invoice
and
from Invoice i join fetch i.Category

2009/8/14 Richard Brown (gmail) <fluk...@googlemail.com<mailto:fluk...@googlemail.com>>


Is there a problem here (that is outside user control) because we implemented this feature implicitly?

With filters on classes, we add the filter inside the class mapping and this only affects queries but not Load/Get using an ID.

With many-to-one relationships (bag/set) we add an explicit filter, or the filter on the class is ignored (a collection without the filter gets everything regardless of the class filter).

With filter on many-to-one ... shouldn't we really make this explicit in the mapping?

e.g., something like:

<many-to-one name="Category" class="Category>
<filter name="validity">ValidUntil > :date</filter>
</many-to-one>

which would make the queries (and loads) eager on that property when the filter is enabled? (Or do we already do this - I couldn't find any test with an example like that)

(I'm just thinking out loud here - hopefully not talking rubbish)

From: Ayende Rahien<mailto:aye...@ayende.com>
Sent: Friday, August 14, 2009 10:40 AM
To: nhibernate-...@googlegroups.com<mailto:nhibernate-...@googlegroups.com>
Subject: [nhibernate-development] Re: Many to one filters

Problem is that eager loading is going to cause _nasty_ issues.
Thing about the potential for Cartesian products, for example, or how much extra data we would have to load.

On Fri, Aug 14, 2009 at 12:25 PM, Richard Brown (gmail) <fluk...@googlemail.com<mailto:fluk...@googlemail.com>> wrote:
I get it. I think you're right, it should eager-load to determine correct result.

From: Ayende Rahien<mailto:aye...@ayende.com>


Sent: Friday, August 14, 2009 10:23 AM

To: nhibernate-...@googlegroups.com<mailto:nhibernate-...@googlegroups.com>


Subject: [nhibernate-development] Re: Many to one filters

Richard,
It isn't working right now for a different reason, because we always put the condition in the where clause, not in the join condition.
I am talking about the actual design, not the impl. I consider the impl. buggy at the moment and will fix it soon.

As for the lazy load scenario, it doesn't work.

Imagine:

var invoice = s.Get<Invoice>(1); // select * from Invoices where Id = 1

Console.WriteLine(invoice.Category.Name<http://invoice.Category.Name>); // select * from Categories where Id =2 and date > @validDate

Now, consider what the options are.
If we lazy load category, we don't know if it is valid or not.
Because we don't know, we put a proxy there for standard lazy loading.
Next, when we do load it, we are in a conundrum. We have what is effectively an invalid object.
NH doesn't let it happen, usually.

Moreover, if we used eager loading in the same scenario, it would throw Null Ref Error.

On Fri, Aug 14, 2009 at 11:40 AM, Richard Brown (gmail) <fluk...@googlemail.com<mailto:fluk...@googlemail.com>> wrote:
Wait, I didn't get that fully. (Probably me be stupid)

If we query, and the query doesn't return the category, I expect the (lazy load) relation to filter it:
invoice.Category should be null (lazy load should filter it);

If we query, and the query does return it (eagerly), still expect the relation to be null:
invoice.Category should also be null (query should filter it);

Which isn't working?

From: Richard Brown (gmail)<mailto:fluk...@googlemail.com>
Sent: Friday, August 14, 2009 8:55 AM
To: nhibernate-development<mailto:nhibernate-...@googlegroups.com>
Subject: Re: [nhibernate-development] Many to one filters

Isn't it consistent to say that the filter will be applied if the table/entity appears in the query?

Although, I understand it looks a little cryptic, since the table might appear in the query due to a FetchMode (like your example), or a lazy="false" in the mapping (more subtle).

Ayende Rahien

unread,
Aug 14, 2009, 5:29:07 PM8/14/09
to nhibernate-...@googlegroups.com
Fabio,
That may be the case, but it means that a perf optimization result in a drastically different behavior in those scenarios.
I would consider this sub optimal.

Ayende Rahien

unread,
Aug 14, 2009, 5:30:09 PM8/14/09
to nhibernate-...@googlegroups.com
Roger,
I agree with you, I don't think we _should_ implement filters on many to one. 
At the very least, they should be explicit.

Fabio Maulo

unread,
Aug 14, 2009, 7:07:54 PM8/14/09
to nhibernate-...@googlegroups.com
2009/8/14 Ayende Rahien <aye...@ayende.com>

Roger,
I agree with you, I don't think we _should_ implement filters on many to one. 
At the very least, they should be explicit.

The filter is something explicit.
The user must activate a filter to have it working.
If you set a filter in an entity you are waiting that NH will filter it every-time, no?... at list I and some others users (see JIRA) are thinking so.
The only one place where the filter have no sense is Get and Load.
--
Fabio Maulo

Ayende Rahien

unread,
Aug 14, 2009, 7:31:42 PM8/14/09
to nhibernate-...@googlegroups.com
Fabio,
I don't think that this is valid, no.
many to one is just another form of direct association, and removing those is not just filtering on queries.
It is changing the shape of entity model

Now, I would have no issue with that, per se. My problem is that it is not consistent.

Fabio Maulo

unread,
Aug 14, 2009, 7:50:08 PM8/14/09
to nhibernate-...@googlegroups.com
If your problem is 
LazyLoadAndEagerLoadShouldHaveSameResult
with a filter activated.
IMO the filter should work even on lazy-load.


2009/8/14 Ayende Rahien <aye...@ayende.com>



--
Fabio Maulo

Ayende Rahien

unread,
Aug 14, 2009, 7:53:31 PM8/14/09
to nhibernate-...@googlegroups.com
Problem, this means that we turn off lazy loading when filter is active.
That has _horrible_ perf implications.

Fabio Maulo

unread,
Aug 14, 2009, 8:20:25 PM8/14/09
to nhibernate-...@googlegroups.com
why turn off ?

I don't understand why this mean turn-off lazy loading.

var invoice = session.Load<Invoice>(3);

hitting invoice.Category the SQL should include filters and work as it is working now with not-found="ignore" (the second part can be done implicitly when there is a filter or we can ask to do it to the user).

2009/8/14 Ayende Rahien <aye...@ayende.com>



--
Fabio Maulo

Ayende Rahien

unread,
Aug 14, 2009, 9:27:33 PM8/14/09
to nhibernate-...@googlegroups.com
Because you can't _do_ that.

var invoice = session.Load<Invoice>(3);

invoice.Category <-- right now it is a proxy, because it is lazy loaded.

invoice.Category.Name <-- force lazy load of the proxy, but if we apply filtering here, the relation will not be found.
What are you going to do then?

Worse, imagine this code

if(invoice.Category != null) // will return true, the result is a proxy
   // do something with category that doesn't exists because of filtering

Fabio Maulo

unread,
Aug 14, 2009, 11:49:36 PM8/14/09
to nhibernate-...@googlegroups.com
well if you think that we can't apply filter even in lazy loading than we can/must apply, for sure, it in case of explicit join.
At most we can "join fetch" on many-to-one may avoid filter but only for Eager loading.

from Invoice i join i.Category <= should apply filter

2009/8/14 Ayende Rahien <aye...@ayende.com>



--
Fabio Maulo

Ayende Rahien

unread,
Aug 14, 2009, 11:52:40 PM8/14/09
to nhibernate-...@googlegroups.com
Sorry, I am not following.
The problematic scenario that I have is not with queries, it is with get of the root entity and then accessing a filtered entity.

Roy R

unread,
Aug 23, 2009, 4:35:35 AM8/23/09
to nhibernate-development
Hi Guys,

Any progress on this issue?

FYI this breaking change had cost us almost a week's work to figure
out and workaround.
We're using filters quite heavily for temporal tables, and to limit
the user's visibility of entities. After upgrading to 2.1, we
encountered about a bug per day (internally) that had something to do
with filters.

So I'm with Roger on this one:
* Filtering on collections makes sense. You get a partial view of the
collection and the model is not broken.
* Once you got hold of an object - however you did that - filtering
out its non-nullable parent doesn't make sense and breaks the model.
Pre-filtering the child still doesn't cover all the holes. What if I
Load/Get the child then try to access its non-nullable parent? The
model guarantees that this child has a parent. The filter guarantees I
will not encounter the "invalidated" parent. Something's gotta give -
and the model is more important IMO.

Roy.

Ayende Rahien

unread,
Aug 23, 2009, 8:45:38 AM8/23/09
to nhibernate-...@googlegroups.com
I got feedback from another user that run into this.

I think we can either:
* enable this only for nullable associations
* provide config option to control this.

Oskar Berggren

unread,
Aug 23, 2009, 10:59:09 AM8/23/09
to nhibernate-...@googlegroups.com
2009/8/23 Ayende Rahien <aye...@ayende.com>:

> I got feedback from another user that run into this.
>
> I think we can either:
> * enable this only for nullable associations

To me that also seems a bit problematic, since a NULL association
would then mean either that there is no associated object or that you
can't see it. Would it be possible to detect which case it is? What
happens if I try to set it to something when there already is a
non-visible association? Would I get an unexpected exception? Or would
the existing association just be silently dropped in favor of the new
one? Could that cause an orphan? Or how to prevent that?


/Oskar

Roy R

unread,
Aug 23, 2009, 11:32:14 AM8/23/09
to nhibernate-development
Enabling it on non-nullable associations will still break the model,
only in a more subtle, hair-pulling way.
If the model dictates that SOME children have parents according to
some biz condition, enabling the filter will nullify some children's
parents which DO fit the biz condition. This a mess to debug.

For example:
An sales Invoice "belongs" to a SalesPerson if it has a reference to
the SalesPerson. Sales people receive commissions from sales. If I get
hold of an Invoice object and check its SalesPerson reference, null
and non-null has a BUSINESS meaning for me. If the filter nullifies
the SalesPerson because "it knows better", the that sales person will
lose its commission.

You might be interested to know that Hibernate for Java does NOT
filter many-to-one associations.

Here is a quote from Java Persistence for Hibernate, Chapter 12:

"
Two object-retrieval methods are /not/ filtered: retrieval by
identifier and navigational access to Item instances (such as from a
Category with aCategory.getItems()).
Retrieval by identifier can't be restricted with a dynamic data
filter. It's also conceptually wrong: If you know the identifier of an
Item, why shouldn't you be allowed to see it? [...] Similar reasoning
applies to filtering of many-to-one or one-to-one associations. If a
many-to-one association was filtered (for example, by returning null
if you call anItem.getSeller()), the multiplicity of the association
would change! This is also conceptually wrong and not the intent of
filters.
"

Roy.

Ayende Rahien

unread,
Aug 23, 2009, 12:02:51 PM8/23/09
to nhibernate-...@googlegroups.com
Committers? 
I am in agreement with Roy here (and the book as well, it seems), I think that applying filters to many to one is a problem.
I think we need a vote around this.

Fabio Maulo

unread,
Aug 23, 2009, 12:39:35 PM8/23/09
to nhibernate-...@googlegroups.com
question:

from Product p join p.Category

A filter about Category.IsActive = false.

In that query the filter should be applied or not ?

2009/8/23 Ayende Rahien <aye...@ayende.com>



--
Fabio Maulo

Ayende Rahien

unread,
Aug 23, 2009, 12:43:02 PM8/23/09
to nhibernate-...@googlegroups.com
No,
But this should work:
select p from Category c join c.Products p

Fabio Maulo

unread,
Aug 23, 2009, 12:52:58 PM8/23/09
to nhibernate-...@googlegroups.com
IMO
from Product p join p.Category
A filter about Category.IsActive = false.

should load only Products where the category is active.
That mean, in SQL, have the condition in the join clause

This other
from Product p left join fetch p.Category
should have the condition in the where clauses (instead the join clause) that mean it should load all Products with a null where the category.IsActive=false.

this other
from Product p left join p.Category should have the condition in the where clauses (instead the join clause)

If we change the behaviour we should have a least a test, with some complex scenario, testing/showing the expected behavior in each case.

2009/8/23 Ayende Rahien <aye...@ayende.com>



--
Fabio Maulo

Ayende Rahien

unread,
Aug 23, 2009, 1:04:59 PM8/23/09
to nhibernate-...@googlegroups.com
Hm...
I am not sure that I am following the logic or agreeing.
This is not a matter of queries, it is a matter of optimization logic.

Let us say that I have a query like:

from Product p where p.Name = :name

And I realize that I am accessing its categories, so I want to do

from product p fetch join p.Category where p.Name = :name

I don't expect, or want, to have this changed. 

Fabio Maulo

unread,
Aug 23, 2009, 1:12:02 PM8/23/09
to nhibernate-...@googlegroups.com
2009/8/23 Ayende Rahien <aye...@ayende.com>

Hm...
I am not sure that I am following the logic or agreeing.
This is not a matter of queries, it is a matter of optimization logic.

Let us say that I have a query like:

from Product p where p.Name = :name

And I realize that I am accessing its categories, so I want to do

from product p fetch join p.Category where p.Name = :name

I don't expect, or want, to have this changed. 

from Product join fetch p.Category <== here you don't want a filter ?

--
Fabio Maulo

Ayende Rahien

unread,
Aug 23, 2009, 1:14:07 PM8/23/09
to nhibernate-...@googlegroups.com
No, I don't. 
For that matter:

s.CreateCriteria<Product>().SetFetchMode("Category");

shouldn't have a filter either.
If I am running a _query_ against Category, I agree that we should apply the filter.
But if it is just perf optimization, I think we should leave it alone.

Fabio Maulo

unread,
Aug 23, 2009, 1:25:38 PM8/23/09
to nhibernate-...@googlegroups.com
oooohhhh it is the same I'm saying above
So, now, we can define a behaviour:
from Product p join p.Category <=== should apply filter

from Product p join fetch p.Category <== shouldn't apply filter

Note: about your previous mail 
select p from Category c join c.Products p <== not possible because in general c.Products does not exists (even if it can be mapped)

resuming for many-to-one:
if the query has, at least, an explicit join it should apply filter
if the query has a "join fetch" shouldn't apply a filter 


Now examples for collections....
from Person p join fetch p.Emails <<== should apply filter on collection ?
The filter is Email.IsActive

2009/8/23 Ayende Rahien <aye...@ayende.com>



--
Fabio Maulo

Ayende Rahien

unread,
Aug 23, 2009, 1:39:28 PM8/23/09
to nhibernate-...@googlegroups.com
inline

On Sun, Aug 23, 2009 at 8:25 PM, Fabio Maulo <fabio...@gmail.com> wrote:
oooohhhh it is the same I'm saying above
So, now, we can define a behaviour:
from Product p join p.Category <=== should apply filter

Hm, I can see your point here...
 

from Product p join fetch p.Category <== shouldn't apply filter

Note: about your previous mail 
select p from Category c join c.Products p <== not possible because in general c.Products does not exists (even if it can be mapped)

yeah, just an example
 

resuming for many-to-one:
if the query has, at least, an explicit join it should apply filter
if the query has a "join fetch" shouldn't apply a filter 

This gets more complex with criteria, though.
 


Now examples for collections....
from Person p join fetch p.Emails <<== should apply filter on collection ?
The filter is Email.IsActive

Yes
Here we explicitly asked to put the filter on the collection

Fabio Maulo

unread,
Aug 23, 2009, 2:18:16 PM8/23/09
to nhibernate-...@googlegroups.com
2009/8/23 Ayende Rahien <aye...@ayende.com>

This gets more complex with criteria, though.

Ok.
Perhaps we can do the same in many-to-one
<many-to-one .....>
<filter ..... />
</many-to-one>

In this case the user will have the full control so whatever is the query (simple "join" or "join fetch") the filter will be applied only is it was specified in the mapping.
What you think about ?

--
Fabio Maulo

Richard Brown (gmail)

unread,
Aug 23, 2009, 2:50:04 PM8/23/09
to nhibernate-...@googlegroups.com
IMHO, I (still) don't think we should ever filter on a many-to-one association without it being explicitly configured in the mapping and also being reflected in the domain model lazy-loading (notwithstanding the problem with being unable to make a proxy magically convert to a null).
 
 
Just to check I'm understanding the previous implementation of filters:
 
 
You can have a filter on an entity (Category in this example).  Any query that has Category as its root entity will apply the filter.  Any query that involves a collection (e.g., the Person.Emails) does not automatically apply the filter on the collection.
 
It is possible to configure the collection to have the filter applied.  If this is turned on, NHibernate:
 
1.  Applies the filter when the association is used in a query;
2.  Also applies the filter when lazy-loading the collection (traversing the model by reachability).
 
The key point is no. 2 ... if we want filtering on many-to-one associations, and the in-memory model to be consistent with the results of a query, then it should be:
 
a)  Explicitly configured on the association (not implicit or a global setting);
b)  Reflected in the model's lazy-loading.
 
(b presumably requiring an eager-load of the association to determine if we should use 'null' instead of the proxy ... and also assuming we ever even agree that 'null' is a sensible thing to have in this case).
 
I hope I'm not missing the point here.
 
Sent: Sunday, August 23, 2009 6:39 PM
Subject: [nhibernate-development] Re: Many to one filters

Richard Brown (gmail)

unread,
Aug 23, 2009, 3:32:05 PM8/23/09
to nhibernate-...@googlegroups.com
And if the property is lazy-loaded through the domain?
Sent: Sunday, August 23, 2009 7:18 PM
Subject: [nhibernate-development] Re: Many to one filters

Fabio Maulo

unread,
Aug 23, 2009, 4:03:14 PM8/23/09
to nhibernate-...@googlegroups.com
2009/8/23 Richard Brown (gmail) <fluk...@googlemail.com>

And if the property is lazy-loaded through the domain?

we can define: filters are not applied in lazy loading.

The matter here is define a well know behaviour and write it in our reference.
So far our reference, about how filters are working, is not clear and for that reason we have this situation.

--
Fabio Maulo

Fabio Maulo

unread,
Aug 23, 2009, 4:03:53 PM8/23/09
to nhibernate-...@googlegroups.com
I mean:  filters are not applied in lazy loading for many-to-one.

2009/8/23 Fabio Maulo <fabio...@gmail.com>



--
Fabio Maulo

Richard Brown (gmail)

unread,
Aug 23, 2009, 4:07:38 PM8/23/09
to nhibernate-...@googlegroups.com
I suspect if we don't do it in the domain, but we do in the query, we'll always end up with a situation where there's an inconsistency .. which I think is where Oren started from way back at the beginning of the thread.
 
I could be wrong though.  At least if it's configured in the mapping, it was explicit - so you can accept the inconsistencies (if there still are any).
 
Sent: Sunday, August 23, 2009 9:03 PM
Subject: [nhibernate-development] Re: Many to one filters

Ayende Rahien

unread,
Aug 23, 2009, 4:36:44 PM8/23/09
to nhibernate-...@googlegroups.com
+1 for that, for sure.

Ayende Rahien

unread,
Aug 23, 2009, 4:37:37 PM8/23/09
to nhibernate-...@googlegroups.com
I actually agree with that.
And we can say that if you define filter for many to one, you also disable lazy loading.
That would give us consistent behavior.

Fabio Maulo

unread,
Aug 23, 2009, 4:40:59 PM8/23/09
to nhibernate-...@googlegroups.com
2009/8/23 Ayende Rahien <aye...@ayende.com>

I actually agree with that.
And we can say that if you define filter for many to one, you also disable lazy loading.
That would give us consistent behavior.

You mean...
disable lazy-loading when the filter is active.

--
Fabio Maulo

Ayende Rahien

unread,
Aug 23, 2009, 4:48:06 PM8/23/09
to nhibernate-...@googlegroups.com
Yes

Fabio Maulo

unread,
Aug 23, 2009, 4:51:07 PM8/23/09
to nhibernate-...@googlegroups.com
2009/8/23 Ayende Rahien <aye...@ayende.com>
Yes

Acceptable solution.

Ok now we should resume and than we can implement it as we have defined.
We will use the resume to write the reference.
--
Fabio Maulo

Roy R

unread,
Aug 24, 2009, 4:10:30 AM8/24/09
to nhibernate-development
IMO it should not be applied, otherwise we would encounter the
problems described above.
This was the behavior up to NH 2.0 and as a heavy user of filters I
was fine with it.

One more note to better explain where I'm coming from:
In NH's unit tests, filters are enabled close to the query. In our
app, some filters are enabled *implicitly* when creating the ambient
session. This allows me to keep all general queries within the user's
scope and the current time. It also means that when I write
Session.CreateQuery() I don't mess around with creating the session
and I usually don't mess around with filters, unless I want to
*disable* them explicitly. If filters start to change the behavior of
the query implicitly (e.g, when eager-loading a filtered entity), this
comes as a surprise to the person who writes the query. It feels like
magic - of the bad kind - and that we should avoid IMO.

Roy.

Fabio Maulo

unread,
Aug 24, 2009, 9:54:49 AM8/24/09
to nhibernate-...@googlegroups.com
2009/8/24 Roy R <royr...@gmail.com>


 If filters start to change the behavior of
the query implicitly (e.g, when eager-loading a filtered entity), this
comes as a surprise to the person who writes the query. It feels like
magic - of the bad kind - and that we should avoid IMO.

This is not the place for this discussion with you but...
What you think the filter feature should do other than "change the behavior of the query implicitly" ?
--
Fabio Maulo

Roy R

unread,
Aug 24, 2009, 10:26:32 AM8/24/09
to nhibernate-development
I'm sorry, maybe I wasn't clear enough: Of course the filters should
change the results of the query. But there are some basic rules in the
MODEL that the programmer relies on, and when they change after
filters are enabled in the "infrastructure" (i.e., in the background
for the programmer), he or she are surprised every time. I've seen it
happen too much in the last few weeks :(

1. Enabling filters should not change the behavior of eager-loading
because it is strictly a performance-related feature; E.g, With the
filter on, query results should stay the same with and without eager-
loading.
2. Enabling filters should not change the multiplicity defined in the
model: Non-null parents should always remain so, and possibly-null
parents depending on biz rules should always remain so. Filters on one-
to-many do not change the multiplicity. Filters on many-to-one do.

Roy.

P.S. Sorry for butting in to the dev mailing list - maybe we should
move the discussion to the users list.

On Aug 24, 4:54 pm, Fabio Maulo <fabioma...@gmail.com> wrote:
> 2009/8/24 Roy R <royra...@gmail.com>

Fabio Maulo

unread,
Aug 24, 2009, 11:00:54 AM8/24/09
to nhibernate-...@googlegroups.com
We had the discussion here and we have the decision... what remain to do is :
- resume
- tests
- implementation
- reference
- short line in breaking changes

2009/8/24 Roy R <royr...@gmail.com>



--
Fabio Maulo
Reply all
Reply to author
Forward
0 new messages