Immutable entities

An immutable entity is an entity that never changes once it has been created. An example could be entries in event log. New log entries may be added all the time; however, once saved, they are not supposed to be modified.

This behavior could of course be enforced in code, or perhaps even in the database, but if we tell NHibernate to treat specific classes as immutable, we can both enforce the immutability and allow NHibernate optimize performance a bit.

Getting ready

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

How to do it…

  1. Add a new folder named ImmutableEntities to the MappingRecipes project.
  2. Add a new class named LogEntry to the folder:
    using System;
    
    namespace MappingRecipes.ImmutableEntities
    {
      public class LogEntry
      {
        public virtual Guid Id { get; protected set; }
        public virtual string Message { get; set; }
      }
    }
  3. Add a new embedded mapping named LogEntry.hbm.xml to the folder:
    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
      assembly="MappingRecipes"
      namespace="MappingRecipes.ImmutableEntities">
      <class name="LogEntry" mutable="false">
        <id name="Id">
          <generator class="guid.comb"/>
        </id>
        <property name="Message"/>
      </class>
    </hibernate-mapping>
  4. Add a new class named Recipe to the folder:
    using System;
    using NH4CookbookHelpers.Mapping;
    using NHibernate;
    
    namespace MappingRecipes.ImmutableEntities
    {
      public class Recipe : HbmMappingRecipe
      {
        protected override void AddInitialData(
          ISession session)
        {
          for (var i = 0; i < 10; i++)
          {
            session.Save(new LogEntry
            {
              Message = "Message " + i
            });
          }
        }
    
        public override void RunQueries(
          ISessionFactory sessionFactory)
        {
          using (var session = sessionFactory.OpenSession())
          {
            using (var tx = session.BeginTransaction())
            {
              var logEntries = 
                session.QueryOver<LogEntry>().List();
              foreach (var logEntry in logEntries)
              {
                logEntry.Message = "Edited message";
              }
              tx.Commit();
            }
          }
    
          using (var session = sessionFactory.OpenSession())
          {
            using (var tx = session.BeginTransaction())
            {
              var logEntries = session.QueryOver<LogEntry>().List();
              foreach (var logEntry in logEntries)
              {
                Console.WriteLine(logEntry.Message);
              }
            }
          }
        }
      }
    }
  5. Run the application and start the ImmutableEntities recipe.

How it works…

In the recipe we tell NHibernate that the LogEntry class should be treated as immutable by adding mutable="false" to the class mapping. We can save a new entry to the database without issues, but if we later on try to modify that entry, nothing happens. NHibernate sees that the entity is immutable and silently ignores any updates that were made. Not only does this protect the entry from being modified, but it also reduces both processor and memory utilization, since no dirty check needs to be performed.

It would seem then that an immutable entity is just silently ignored when NHibernate updates the database. That is not entirely true, though. Some things may still happen:

  • Immutable entities can be deleted
  • If the immutable entity has a collection property (one-to-many or many-to-many), this collection will be persisted to the database if it is modified.
  • If the entity is versioned, using the version mapping, a collection modification will cause the version to be updated.

NHibernate can also make entities read-only on demand. This can be useful when one part of the application is allowed to modify the entries, but another part, like the public front end of a web site, only should be used for reading and querying. We will dig deeper into that in Chapter 5, Improving Performance.

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

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