Fluent NHibernate - avoid loading children collection - nhibernate

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

Related

NHibernate: removing from collection vs association and cascading styles

I'm having trouble understanding how NHibernate knows anything about objects removed from association (and then execute cascading style like delete-orphant). I mean, at a database level if I wanted to remove an association I'd have to physically log on and remove some FK. How does this happen in NH world? Do I remap my classes, remove previously established parent/child association (relationship), NH does comparative analysis, digs that something has been changed and then takes appropriate action? In this post Ayende talks about different cascading styles and delete-orphat is described as "... In addition to that, when an object is removed from the assoication and not assoicated with another object (orphaned), also delete it ..." How does this removal happen?
NHibernate watches all the mapped collections mapped that are owned by objects in the NHibernate session. As you make changes (adding/removing) NHibernate marks them as dirty. When it is time to flush the changes it compares the elements in the dirty collections and is able to identify what items have been added and removed. Depending on the cascade options for the collection NHibernate might then persist those changes to the database.
This is why you should always declare collection properties using interfaces (IList, ISet, etc.) and never replace a collection property on an object that has been loaded using NHibernate.
Additional info requested in comments:
There is a useful discussion by Fabio Maulo (NHibernate lead developer) of collection mapping here which I would strongly recommend to read. But to try and provide a brief answer to your questions:
But how does NH know that association between objects has been removed?
Generally when working in the OO model with many associations we manage relationships at the parent. That is, a child is considered to be associated with the parent when it is in a parent's collection. E.g.
child.Parent = parent;
parent.Children.Add(child); // This is the critical bit
session.Save(parent); // to have an INSERT generated here
Similarly removing an item from a collection breaks the association (assuming correct mapping attributes have used)
child.Parent = null;
parent.Children.Remove(child); // This is critical bit
session.Save(parent); // To have DELETE or UPDATE statement generated depending on cascade settings.
This is the opposite of how things work in the relational world where we manage the relationship at the child via the foreign key on the child row.
For a more detailed understanding there is nothing like downloading the NHibernate source code, creating a simple test case and then stepping through in the debugger.
What's the reason behind the "This is why..."
There are a number of things NHibernate takes care of in managing in association collections. It does this by using its own collection classes that keep track of whether they are dirty, what state they were in when they were loaded from the db and a number of other cool things. If you replace those objects then NHibernate loses that capability. So, for instance if you want to get rid of all the items in a collection you should do:
parent.Children.Clear(); // The collection object is preserved and NHibernate knows you want them all deleted.
You should NEVER do:
parent.Children = new List<X>(); // NHibernate will not track changes to this collection.
For further reading you might also want to take a look at this.

HIbernate - bulk loading child objects

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.

eagerly load an entity object graph in nhibernate

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.

When can I use Unidirectional relationships in NHibernate?

I'm trying to port a large graph of .NET entities to use NHibernate, but I'm encountering an issue that most of the relationships are only defined unidirectionally - in most cases, the child class contains a reference to the parent, but the parent does not contain the collection of refs to its children. It would be quite a bit of work to add all the collections to turn the relationships into bidirectional ones, so I'm wondering what the consequences for NHibernate would be of not doing so?
One consequence I've noticed is that cascading deletes seem to fail (child doesn't get deleted in the DB, causing a referential integrity violation). Is that the only consequence or are there other issues I need to be aware of?
Are there any guidelines for when relationships should be uni or bi-directional?
Thanks
I think that not being able to cascade the deletes will be the only issue with NHibernate per se.
But you will not be able to easily walk the graph. You can do it from child to parent, but obviously not from parent to child. So you would have to issue a query each time you want all the childs from a parent.
So if you are using NH for a persisted domain model, where you have a root object from which you need to use the child objects for certain operations, you would have to issue queries from within the model to get the children. So your model will be coupled to your data access.
Or you would have to pass the children to the parent object as collections, but then it might be just at easy to have the collections on the model to begin width so NH could fill them for you.

Can a collection in NHibernate be mapped as read-only?

I have a mapping defined where a parent object has a collection of child objects. In my design, I'd like to be able to delete the child objects without having to remove them from the collection on the parent object and re-saving the parent object. However, when I try this, I get the "deleted object would be re-created on save" error. Is there a way to prevent this such that I could simply delete the child object and not worry about removing it from the parent's collection too? That feels like doing double the work. Ideally I'd like to treat the parent's collection as read-only from NHibernate's perspective.
It'd help if you post your mapping files, but it sounds like you need to add Inverse=true to the collection mapping. This means that the child object is responsible for handling any save or updates, not the parent.
However, in the database it's all modelled the same. The child should have a column for the parent row's ID. NHibernate will create different SQL based on the Inverse property though. I'd like to give more detail, but I'm learning NHibernate myself as well.
I believe the only thing you need to do is just set the collection of child objects in the parent's mapping file to be cascade="none".
Of course that will also prevent saving child objects by assigning them to the parent's collection and updating the parent. If that is OK then you got your solution.