How can I get NHibernate to hook up child objects automatically or bulk load children rather than lazy loading for each parent?
I have a large number of parent objects all of the same type. Each of them has two bags of child objects. As I need to load all the parents and children objects as quickly as possible, I use NHibernate to load all the objects and then loop all child objects and add them to relevant parent in code. I'm sure NHibernate has a much better way of doing this - but what is it?
You can always use eager loading behavior of NHibernate to override its default behavior (Lazy Loading).
Here is an article that discuss lazy loading and eagerly loading
Take a look at the "Eagerly loading with HQL" part that shows how you can use HQL to eagerly load an object graph.
However using eager loading can have a negative impact on performance specially if you are working with a lot of objects.
Related
I am working on a legacy application where NHibernate has been used without any apparent thought to efficiency. I am currently stepping through a method in which over 200 queries have been executed so far. This is mostly due to the N+1 problem.
Anyway, as I think about fixing this, my question is:
Given an entity with, say, 10 child collections, almost all of which will be accessed during a single operation, is there a way to lazy-load each child collection in a single call rather than have NHibernate lazy-load each individual child record as it is accessed (e.g., in a foreach loop, which is what's happening now). It seems to me that eager loading all of these child collections at once would be a massive query and not very performant. But obviously this N+1 approach is wrong. How can I tell NHibernate to do a query that loads up the whole child collection on demand? This still gives me 11 queries, but it's better than 200 and, perhaps, better than the massive query I'd have to do if I eager loaded everything.
Thanks!
You can use the method NHibernateUtil.Initialize(yourObject.ChildCollection). This method forces proxies to load their data based on their fetching strategy, that you set in your mappings. Source: NHibernate documentation
I am not understanding the following scenario. I have a situation where I need to load children and grandchildren along with an entity. I have specified that collections are lazyloaded, but eagerly fetch all rows using detached criteria and setfetchmode to eager. I have the following problem:
NHibernate is taking very long to hydrate the objects - the actual queries run quickly though.
I place the list of results into .net MemoryCacheManager object and seems that after a while the grandchildren seem to drop out the object and I get a lazyload exception.
How to I ensure that the entire graph returned by the results remains in tact in the MemoryCacheManager object? Does session.Evict help me?
Ended up using QueryOver future queries and flattened the results into a DTO and ended up caching the DTO.
I have set NHibernate to not lazy load for my entities. But sometimes when I do queries I don't want all the children of the children to be loaded. The mapping is set up by Fluent NHibernate.
Is there any way when writing the sql for the query to specify which columns to lazy load?
I believe, you're using the wrong approach. Set all mappings to lazy load, and then in the queries eager load only what you really need. This way you won't kill the app.
You can override all the mappings defined in Fluent Mappings in conventions either in class mappings.
There also are different scenarios where NHibernate does the trick (for instance if you load / get one instance all the properties will be fetched as defined in mapping. If you get a list of items it will not happen unless you use Fetch method explicitly).
So could you provide some more details on your question to give an answer that is more precise?
I have 2 classes with HasMany relationship, say a class called Parent that has a collection of Children. I want to be able to build queries in NHibernate that would only return Parents that have Children. I guess that to do that I need to have this HasMany relationship.
What I want though is following - when I load Parents, I don't want it's children to be loaded. Kind of LazyLoading, but without loading Children at all.
Any ideas how to accomplish this?
NHibernate's LazyLoading of collections is exactly what you asked for. The collection-object itself is created but none of the child objects is loaded.
When JSON method is called Children objects are loaded lazily. I want to avoid it.
3 Options come to mind
projecting the Parentobject into a DTO which is then serialized
Customizing the JSON serialization
detaching the parent from the session (Evict()) and setting the collection to null before serializing
i would favor option 1, but option 2 would be ok too. Option 3 would be a hack and should be avoided
I am looking for a way to get the entire object graph back from one of my nhibernate persisted entities. Is there a way to turn off lazy loading in a sessionfactory,session or query?
I have tried setting the FetchMode but it does not eagerly load the entity and child collections.
I just need this for one object to export it out of the database.
You can use CreateMultiQuery or CreateMultiCriteria and keep the default behavior to lazy loading in your mapping.
Take a look at this article for details.