10
votes

I would like to know if there is a way to disable automatic loading of child records in nHibernate ( for one:many relationships ).

We can easily switch off lazy loading on properties but what I want is to disable any kind of automatic loading ( lazy and non lazy both ). I only want to load data via query ( i.e. HQL or Criteria )

I would still like to define the relationship between parent child records in the mapping file to facilitate HQL and be able to join parent child entities, but I do not want the child records to be loaded as part of the parent record unless a query on the parent record explicitly states that ( via eager fetch, etc ).

Example: Fetching Department record from the database should not fetch all employee records from the database because it may never be needed.

One option here is to set the Employees collection on Department as lazy load. The problem with this approach is that once the object is given to the calling API it can 'touch' the lazy load property and that will fetch the entire list from the db.

I tried to use 'evict' - to disconnect the object but it does not seem to be working at all times and does not do a deep evict on the object. Plus it abstracts the lazy loaded property type with a proxy class that plays havoc later in the code where we are trying to operate on the object via reflection and it encounters unexpended type on the object.

I am a beginner to nHibernate, any pointers or help would be of great help.

2
You have a typo: disbale -> disableAnthony

2 Answers

3
votes

Given your request, you could simply not map from Department to Employees, nor have an Employees property on your department. This would mean you always have to make a database hit to find the employees of a database.

Aplogies if these code examples don't work out of the box, I'm not near a compiler at the moment

So, your department class might look like:

 public class Department 
 { 
     public int Id { get; protected set; }
     public string Name { get; set; }
     /* Equality and GetHashCode here */
 }

and your Employee would look like:

 public class Employee
 { 
     public int Id { get; protected set; }
     public Name Name { get; set; }
     public Department Department { get; set; }
     /* Equality and GetHashCode here */
 }

Any time you wanted to find Employees for a department, you've have to call:

/*...*/
session.CreateCriteria(typeof(Employee))
    .Add(Restrictions.Eq("Department", department)
    .List<Employee>();

Simply because your spec says "Departments have many Employees", doesn't mean you have to map it as a bi-directional association. If you can keep your associated uni-directional, you can really get your data-access to fly too.

Google "Domain Driven Design" Aggregate, or see Page 125 of Eric Evan's book on Domain Driven Design for more information

-1
votes

You can have the lazy attribute on the collection. In your example, Department has n employees, if lazy is enabled, the employees will not be loaded by default when you load a department : http://www.nhforge.org/doc/nh/en/#collections-lazy

You can have queries that explicitly load department AND employees together. It's the "fetch" option : http://www.nhforge.org/doc/nh/en/#performance-fetching-lazy