Using lazy properties

Consider a class representing a scientific article, with properties for author, title, abstract, full text, and so on.

This looks simple enough, but having the full article text stored in the entity could cause serious issues. The text may be several megabytes in size and if we're, for example, just listing the available articles, it's very unnecessary to load all that from the database and storing it in memory.

Thankfully, NHibernate has a solution for this, called lazy properties. Just as with lazy loading of referenced entities and collections, this function will not load the data until it is accessed.

Getting ready

Complete the Getting ready instructions at the beginning of this chapter.

How to do it…

  1. Add a new folder named LazyProperties to the MappingRecipes project.
  2. Add a class named Article to the folder:
    namespace MappingRecipes.LazyProperties
    {
      public class Article
      {
        public virtual int Id { get; protected set; }
        public virtual string Title { get; set; }
        public virtual string Abstract { get; set; }
        public virtual string Author { get; set; }
        public virtual string FullText { get; set; }
      }
    }
  3. Add a new embedded mapping named Article.hbm.xml to the folder:
    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
      assembly="MappingRecipes"
      namespace="MappingRecipes.LazyProperties">
      <class name="Article">
        <id name="Id">
          <generator class="native"/>
        </id>
        <property name="Title"/>
        <property name="Abstract"/>
        <property name="Author"/>
        <property name="FullText" lazy="true"/>
      </class>
    </hibernate-mapping>
  4. Add a class named Recipe to the folder:
    using System;
    using NH4CookbookHelpers;
    using NHibernate;
    
    namespace MappingRecipes.LazyProperties
    {
      public class Recipe : HbmMappingRecipe
      {
        protected override void AddInitialData(ISession session)
        {
          session.Save(new Article
          {
            Title = "Lazy properties",
            Author = "NHibernate",
            Abstract = "Supporting lazy properties is cool",
            FullText = "An enourmously long text"
          });
        }
    
        public override void RunQueries(ISession session)
        {
          var article = session.Get<Article>(1);
          Console.WriteLine("Title:" + article.Title);
          Console.WriteLine("Author:" + article.Author);
          Console.WriteLine("Abstract:" + article.Abstract);
          Console.WriteLine("Has fulltext been loaded: {0}",
            NHibernateUtil.IsPropertyInitialized(article,"FullText"));
          Console.WriteLine("Full text:" + article.FullText);
    
        }
      }
    }
  5. Run the application and start the LazyProperties recipe.

How it works…

Lazy properties work similarly to how lazy loaded relations work. When the Article is loaded from the database, the FullText column and its data is ignored. Instead, it's loaded immediately when the FullText property is used for the first time.

NHibernate accomplishes this by instantiating the Article entity as a proxy class, in other words a dynamically generated subclass of Article. This proxy intercepts any call to the FullText property, and if necessary asks the session to load the text.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.20.20