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.
LazyProperties
to the MappingRecipes
project.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; } } }
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>
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); } } }
LazyProperties
recipe.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.
3.139.86.18