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.
ImmutableEntities
to the MappingRecipes
project.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; } } }
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>
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); } } } } } }
ImmutableEntities
recipe.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:
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.
18.221.241.116