views:

1537

answers:

3

I'm working with a legacy system that I'm experimenting with adding NHibernate to. I have class that I need to be mapped to a table, but it has lots of existing methods that are not virtual.

I discovered that I can get NHibernate to load the mapping successfully even with the non-virtual methods present if I set the "lazy" attribute on the class element of the mapping file to "false". I'm wondering what impact this will have on my use of NHibernate with this class.

I understand the meaning of non-lazy loading on collections that belong to an object, but I'm not clear on the meaning of what lazy or eager loading on a class would be. Does that mean all collections belonging to that object would be eager-loaded? Or does it mean that NHibernate no longer uses a dynamic proxy in place of the actual class? Something else?

Also, what's the best course of action here? Is setting that lazy=false value inadvisable? Should I create an interface that the class implements, and then map that to the table? Or should I just bite the bullet and mark all the existing methods on the class virtual?

Thanks in advance for any and all advice!

+2  A: 

I always specify lazy=false on the class level in NHIbernate, because I do not want that NHibernate forces me to declare that properties are to be virtual, if I do not want this in my class-model.

When you specify 'lazy' at the class mapping (default), NHibernate uses a 'Dynamic Proxy' class at runtime. This Dynamic Proxy is a class that inherits from your class. Then, as far as I understand, the instance of the class should be initialized lazily / on-demand. In some cases, this should be better for performance (at least, that's what's being told).

But, since I do not like that NHibernate tells me how my class should look like, I've always specified lazy=false for all my classes, and I haven't ran into trouble yet. :)

Frederik Gheysels
So, to be clear before marking your answer as accepted, setting lazy=false on the class level will not cause that class' collections to be eager loaded?
Brian Sullivan
No, the lazy attribute at the class level has no impact on the lazy attribute at collection levels.(I do have classes where I specify lazy=false at class level, and lazy=false at collection level)
Frederik Gheysels
Thanks, Frederik! Very helpful!
Brian Sullivan
A: 

Using lazy loading is very effective at limiting the number of objects. This feature can be extremely useful in certain situations. For example, imagine you had two objects User and Role and that all Users have 1 or more roles. When you load the User object, you would also want to load all of its associated Roles. However, when you load the Roles for that User, you would not want to load all of the Users associated with that Role because that may wind up loading the entire database of Users.

So setting lazy = false means that the entire collection of objects for the relationship will be loaded when the calling instance is loaded. In some situations, this is fine, good, and appropriate, in other situations, this can lead to performance issues.

Rob Di Marco
+1 for the 'in some situations'. Fetching lazy or not lazy should indeed be defined per use case!
Hace
+1  A: 

Rob, That's just bad design. User will have List of type Role but Role will not have List of type User. User is an aggregate root, to get all users in a role, define a method on User to GetByRole(). 2 way traversals like you described make a horrible domain model. Google 'circular references' and see why it is bad.

See inverse collections
Min