Can i said NH somehow, "thats all i need to select for that collection" ? :)
On Fri, Oct 3, 2008 at 7:14 PM, Andrew Melnichuk <[EMAIL PROTECTED] > wrote: > Ok i see. > Yes, approach from blog post will work. But the deeper collection have to > be fetched, the bigger cartesian product will be returned. I have 5-6 levels > tree. > > > On Fri, Oct 3, 2008 at 7:10 PM, Ken Egozi <[EMAIL PROTECTED]> wrote: > >> ok, here's why it's not working: >> >> when you access c.Customers, NH can't be sure that all of the relevant >> customers for c are loaded. so it's going to the DB. >> the approach described in the said blog post is loading the child >> collection based on a join to the type it belongs to >> >> so, "select cs from Country c join fetch c.Customers cs where c = :c" >> should work. >> >> On Fri, Oct 3, 2008 at 7:04 PM, Andrew Melnichuk < >> [EMAIL PROTECTED]> wrote: >> >>> Just to be sure... if NH logs sql statement, is it 100% will reach db? >>> I'm just using SQLite inmemory mode, can't use profiler. >>> >>> >>> On Fri, Oct 3, 2008 at 7:03 PM, Andrew Melnichuk < >>> [EMAIL PROTECTED]> wrote: >>> >>>> I changed >>>> Assert.That(NHibernateUtil.IsInitialized(c.Customers)); >>>> to >>>> Assert.That(c.Customers.Count == 2); >>>> >>>> and it still hits the db, here is the SQL >>>> >>>> // for root >>>> select country0_.Id as Id0_, country0_.Name as Name0_ from Country >>>> country0_ where (Name='Germany' ) >>>> >>>> // for collection >>>> select customer0_.Id as Id1_, customer0_.Name as Name1_, >>>> customer0_.CountryId as CountryId1_ from Customer customer0_ where >>>> ([EMAIL PROTECTED] )and(customer0_.Name='GermanyCustomer1' ); @p0 = >>>> '1' >>>> >>>> // for collection.count >>>> SELECT customers0_.CountryId as CountryId1_, customers0_.Id as Id1_, >>>> customers0_.Id as Id1_0_, customers0_.Name as Name1_0_, >>>> customers0_.CountryId as CountryId1_0_ FROM Customer customers0_ WHERE >>>> [EMAIL PROTECTED]; @p0 = '1' >>>> >>>> >>>> >>>> On Fri, Oct 3, 2008 at 6:54 PM, Ken Egozi <[EMAIL PROTECTED]> wrote: >>>> >>>>> try to simply access the c.Customers and check (via show-sql or DB >>>>> profiler) that the DB is not being hit, but the customers data is being >>>>> hooked from the session cache. >>>>> >>>>> >>>>> On Fri, Oct 3, 2008 at 6:40 PM, Andrew Melnichuk < >>>>> [EMAIL PROTECTED]> wrote: >>>>> >>>>>> Hi all. >>>>>> >>>>>> I have a complex object graph. There is a root entity which has a set >>>>>> of collections (some of them are pretty big), entities in collections >>>>>> have >>>>>> their own collections etc.. - a kind of tree. I need to fetch this tree >>>>>> with >>>>>> minimum performance hit for database. I have tried 2 options for now: >>>>>> 1st - load root entity, and then navigate through properties to load >>>>>> all child and grandchild collections, ofcourse set fetch="subselect" in >>>>>> mapping file before, to prevent select n+1 problem >>>>>> 2nd - use approach, described here >>>>>> http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/06/eager-loading-aggregate-with-many-child-collections.aspx, >>>>>> where different collections load by different queries, but session is >>>>>> smart >>>>>> enough, to merge different result to object graph, initializing different >>>>>> collections. >>>>>> >>>>>> But i can't use 1st approach, because i can't define fetch plan on a >>>>>> global level (number of reasons), and i can't use 2nd approach, because >>>>>> it >>>>>> seems that it works fine for 1st level collection only, selecting deeper >>>>>> level collections will produce cartesian product, which will grow with >>>>>> level >>>>>> of query of collection. >>>>>> >>>>>> What i thought about, is would it be possible to use approach based on >>>>>> several queries, like 2nd approach i mentioned. The difference is i >>>>>> tried to >>>>>> start fetching not from the root entity level, but from the level i have >>>>>> to >>>>>> fetch next, after i already fetched with previous query. For example: >>>>>> >>>>>> [Test] >>>>>> public void Test1() >>>>>> { >>>>>> // load root entity >>>>>> Country c = _session >>>>>> .CreateQuery("from Country where Name = 'Germany'") >>>>>> .List<Country>()[0]; >>>>>> >>>>>> // trying to load 1st level child collection >>>>>> _sess >>>>>> .CreateQuery("from Customer cs where cs.Country = :c") >>>>>> .SetParameter("c", c) >>>>>> .List(); >>>>>> >>>>>> Assert.That(NHibernateUtil.IsInitialized(c.Customers)); // >>>>>> fails >>>>>> } >>>>>> >>>>>> I thought that session will initialize Country.Customers collection, >>>>>> but it is not. >>>>>> Ofcourse i could use eager join for this collection and others at the >>>>>> same level, but as i said this will causes cartesian product for deeper >>>>>> collections. >>>>>> I'm not sure that what i did is valid, maybe it is invalid by design, >>>>>> however it seems that session can initialize customers collection, since >>>>>> it >>>>>> "knows" to which country selected customers belongs. >>>>>> >>>>>> Just wanted to ask, how people solve same problems. >>>>>> >>>>>> -- >>>>>> Best regards, >>>>>> Andrew Melnichuk >>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>>> -- >>>>> Ken Egozi. >>>>> http://www.kenegozi.com/blog >>>>> http://www.musicglue.com >>>>> http://www.castleproject.org >>>>> http://www.gotfriends.co.il >>>>> >>>>> >>>>> >>>> >>>> >>>> -- >>>> Best regards, >>>> Andrew Melnichuk >>>> >>> >>> >>> >>> -- >>> Best regards, >>> Andrew Melnichuk >>> >>> >>> >> >> >> -- >> Ken Egozi. >> http://www.kenegozi.com/blog >> http://www.musicglue.com >> http://www.castleproject.org >> http://www.gotfriends.co.il >> >> >> >> > > > -- > Best regards, > Andrew Melnichuk > -- Best regards, Andrew Melnichuk --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "nhusers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/nhusers?hl=en -~----------~----~----~----~------~----~------~--~---
