Here is an interesting tidbit on using the lazy and outer-join property in Set mapping. A Set is a collection of unique items and is optimized for reading and writing. When using Set remember to assign a data type of HashSet in your class.

The lazy property is by default is set to true. If your code does a session.Get<T> and uses a foreach loop on the Set NHibernate will generate two select statements. Even if you change the lazy property to false you still get two select statements because NHibernate does not control how the Set is loaded. NHibernate in order to avoid the possibility of a Cartesian product generates the two select statements.

When the lazy property is false the Set is loaded when the .Get<T> is called. When the lazy property is set to true then the collection will only be loaded in the foreach loop.

If you want to load both the entity and the Set is a single SQL statement then you must use the outer-join property set to true. However, this is an expensive operations if you only need the Set loaded for certain situations. It is recommended that you don’t set the outer-join property to true.

What should you do? You should manage this at a higher level and not in the mapping. If you need all of the records in a Set to be loaded with the entity then you would use .SetFetchMode as part of your query. This would look something like this:

var myEntity = session.CreateCriteria<T>().SetFetchMode("U",FetchMode.Join).List();

where <T> is the class and U is the Set within the class.