views:

2256

answers:

2

It took me a long time but I finally got nHibernate's Hello World to work. It worked after I did "lazy loading." Honestly, I couldn't tell you why it all worked, but it did and now I am reading you don't need lazy loading. Is there a hello world that anyone has that is bare bones making nHibernate work? Do you have to have lazy loading? I ask because I would like to use nHibernate but I need to understand how things are working.

Thank you.

Do you know of a hello world that doesn't have so much overhead?

Is it better to use lazy loading?

EDIT: I am using asp.net 3.5. Web Application Project.

+3  A: 

If you're using hbm.xml files for you mapping simply adding a lazy="false" to the <class> element will get you non-lazy loading for all simple properties. Foreign entities will still be lazy by default. To make them eager add lazy="false" to the mapping element. One benefit of eager loading is you will no longer need virtual properties on your entity classes.

Edit: If you really want to find out what's going on behind the scenes, NHibernate logs everything using log4net. Adding

<configSections>
  <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  <!-- Rest of config sections here -->
</configSections>
<log4net>
  <appender name="SQLFileAppender" type="log4net.Appender.RollingFileAppender, log4net">
    <param name="File" value="C:\Logs\SQL.log" />
    <param name="AppendToFile" value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <param name="ConversionPattern" value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
  </appender>
  <logger name="NHibernate.SQL" additivity="false">
    <level value="DEBUG" />
    <appender-ref ref="SQLFileAppender" />
  </logger>
</log4net>

inside <configuration> in your web.config will spit all the SQL NHibernate generates the file c:\logs\sql.log

Jeff Mc
+6  A: 

I don't understand what you mean with "I did lazy loading". Lazy loading is a feature, it is turned on by default and you can turn it off if you don't like it.

There are two kinds of lazy loading: for references to other entities and for lists.

Given this entity:

class Entity
{
  // pk
  int id { get; private set; }

  // reference to another entity
  User MyUser { get; set; }

  // list to other entities
  IList<Comments> MyComments { get; set; }
}

Lazy loading on the reference to User

If you have lazy loading on the User, you need to define all members of the User class virtual. NHibernate will create a so called proxy. The proxy is a classed defined at runtime which derives from User. Your code is accessing it as User and is not aware that is is a subclass. But when you access one of its members the first time, the properties are loaded from the database.

If you want to turn off lazy loading on the User class, you need to do this in its mapping:

<class name="User" lazy="false"> ...

Then NHibernate creates always instances of type User, no proxies. You don't need to have anything virtual.

Lazy loading on the list of comments

If you use lazy loading on the list of comments, it is the list itself that implements the lazy loading. If you access the list the first time, it is loaded from the database. NHibernate uses a list that implements IList, but is not List.

If you want to turn off lazy loading in the list, you do this in the mapping of Entity:

<class name="Entity">
    <bag name="MyComments" lazy="false" >
        ...

Usually, lazy loading is a good thing, and you application does not have to care about it much. But there are some risks. For instance, if you serialize a instance, and it is a proxy, you get a not initialized proxy instead of anything useful. Lazy loading only works as long as the session is open. It is not always faster to use lazy loading. If you need to load all the data anyway, its faster to load it in one piece.

So the configuration needs to be done carefully.


Edit:

To answer your original question: Is lazy loading required for NHibernate? No. But: Is lazy loading required in my application? Most probably yes.

I think, only small and rather trivial applications don't need lazy loading. If you have a system with many persistent classes, you'll need lazy loading.

Stefan Steinegger