Relations with not-found=”ignore” disable lazy load and impact on performances

NHibernate has a lot of interesting and specific option for mapping entities that can really cover every scenario you have in mind, but you need to be aware of every implication each advanced option has on performances.

If you are in a legacy-database scenario where entity A reference Entity B, but someone outside the control of NHibernate can delete record from table used by Entity B, without setting the corresponding referencing field on Entity A. We will end with a Database with broken reference, where rows from Table A references with a field id a record in Table B that no longer exists. When this happens, if you load an Entity of type A that reference an Entity of type B that was deleted, it will throw an exception if you try to access navigation property, because NHibernate cannot find related entity in the Database.

If you know NHibernate you can use the not-found=”Ignore” mapping option, that basically tells NHibernate to ignore a broken reference key, if EntityA references an Entity B that was already deleted from database, the reference will be ignored, navigation property will be set to Null, and no exception occurs. This kind of solution is not without side effects, first of all you will find that Every time you load an Entity of Type A another query is issued to the database to verify if related Entity B is really there. This actually disable lazy load, because related entity is always selected. This is not an optimum scenario, because you will end with a lot of extra query and this happens because not-found=”ignore” is only a way to avoid a real problem: you have broken foreign-key in your database.

My suggestion is, fix data in database, keep the database clean without broken foreign-keys and remove all not-found=”ignore” mapping option unless you really have no other solution. Please remember that even if you are using NHibernate, you should not forget SQL capabilities. As an example SQL Server (and quite all of the relational database in the market) has the ability to setup rules for foreign-key, es ON DELETE SET NULL that automatically set to null a foreign key on a table, when related record is deleted. Such a feature will prevent you from having broken foreign key, even if some legacy process manipulates the database deleting records without corresponding update in related foreign-key.

Gian Maria.

NHibernate 3.2 and Mapping By Code

In version 3.2 of NHibernate a new mapping capabilities was introduced to easy mapping of entities in your project. To understand how it works and how easy it is here it is all initialization code you need if you want to accept default mapping rules for all of your classes.

cfg = new Configuration();
var mapper = new ConventionModelMapper();
mapper.IsEntity((t, declared) => t.Namespace.StartsWith("Myproject.Entities"));
mapper.AfterMapClass += (inspector, type, classCustomizer) =>
var mapping = mapper.CompileMappingFor(
    .Where(t => t.Namespace.StartsWith("Myproject.Entities")));

cfg.AddDeserializedMapping(mapping, "AutoModel");

Basically I’m creating a ConvetionModelMapper that is capable of mapping entities by convention, then the IsEntity method is used to specify a condition to make the mapper aware of the classes that needs to be mapped; in this example I simply states that everything that is in namespace Myproject.Entities should be mapped. Since I want lazy load to be disabled I register an handler on AfterMapClass, an event that is launched whenever an entity is mapped, and I simply disable lazy load stating Lazy(false).

In this super simple example all the entities are in the same assembly of this function, so I can pass the executing assembly to the CompileMappingFor() method of conventional mapper, specifying again the list of class I want to be mapped. Finally I can simply use AddDeserializedMapping method of Configuration object to add the mapping generated by CompileMappingFor and the game is done. Now you can create this simple class in Myproject.Entities

public class Customer

    public Int32 Id { get; set; }

    public String Name { get; set; }

    public String Surname { get; set; }

And let NHibernate generate the database, you got this table automatically generated in the database.


Figure 1: Table generates by automapping in the database.

The main problem of this approach is that this table has not Identity on Id column and all the nvarchar columns have 255 length, because this is the default of NHibnernate. Now you can solve this problem with two different approaches, the first is keeping track of your database with a different tool, like Database Projects in Visual Studio, because probably you have other part of the database that is not related to nhibernate (like stored procedure) that you need to manage. To simply this process I usually let nhibernate generate a test database when I add new entities, then I simply synchronize my database project to grab all the differencies, and then I refine them adding identities, length etc.

If you want NHibernate to manage all stuff of database creation and Updating, you need to give more detail to the Conventional mapper. Here is an example.

mapper.Class<Customer>(map => map.Id(c => c.Id, mapInfo => mapInfo.Generator(Generators.Native)));
mapper.Class<Customer>(map => map.Property(c => c.Surname, mapInfo => mapInfo.Length(40)));
mapper.Class<Customer>(map => map.Property(c => c.Name, mapInfo => mapInfo.Length(40)));

This approach can be useful if you have few entities, but when your domain is quite complex, it is slightly better to use a Database Project that gave you more control over the structure of the database with a tool dedicated to this purpose.

Gian Maria.

Troubleshoot WCF The underlying connection was closed: A connection that was expected to be kept alive was closed by the server

I’ve already blogged in the past on how to easily troubleshoot WCF Exception and that suggestion is valid for every exception you encounter in WCF. Today I have a function that gave the error

System.ServiceModel.CommunicationException: The underlying connection was closed: A connection that was expected to be kept alive was closed by the server. —> System.Net.WebException: The underlying connection was closed: A connection that was expected to be kept alive was closed by the server. —> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. —> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host

This problem is usually caused by some error in the communication channel, but even in such a situation, enabling the trace listener immediately gave to you an idea of the problem.



Figure 1: How to identify the problem thanks to WCF Trace Listener

In my situation the error is ClientProxy …. is not expected and this is due to the fact that I’m returning from WCF a couple of classes that are mapped with NHIbernate, the entity returned has a property of type Customer that is a lazy property, thus at runtime it is represented by a dynamic proxy that is not known to WCF. The solution is trivial, just issue a Fetch(obj => obj.Client) in the LINQ query to fetch Client and avoiding NH to create a proxy, but the key point is that with WCF trace listener, finding problems in WCF is matter of few seconds.

Gian MAria.


Unit test NHibernate query to verify N+1

When you work with ORM like nhibernate, having a tool like nhprof is the key of success. But even with NHProfiler you could not prevent people of doing wrong stuff because they do not use it :). I have a simple scenario, a developer changed a method on the server lazily fetching a property of a large resultset. The effect is that the service call, that usually responded in milliseconds starts to respond in 10 seconds.

The reason is really simple, the function loaded about 200 entities from the database and if you are sure you want to access for all 200 entities a property, you should do eager fetching because issuing ~200 queries to the database is not usually a good idea. Then after some time the function started to do timeout, so I inspected again the code and did not find anything strange, but NHprof reveals me that the query was actually fetching another related entity, from a table with millions of row causing timeout. This is due to a modification to a mapping, someone disabled proxy for that class, so NH decided to do a join with the table with millions of row, slowing the method again .

After the problem was fixed, I created some helpers that permits me to write a test that will alert me immediately in the future if such a problem is comeback again.

   1: [Test]

   2: public void verify_xxxx()

   3: {

   4:     var sut = new cccccService();

   5:     sut.DoSomething(1);

   6:     this.NhibernateQueryCount().Should().Be.EqualTo(1);

   7:     String query = this.NhibernateGetQueries().First();

   8:     query.Should().Not.Contain("relatedlin1_.Id");

   9: }

This test is not really a UnitTest, it is more an integration one, but it is able to verify that calling a function on a service class only one query is issued to the database and the query should not eager fetch data from the other table (relatedlin…). This is much more an integration test than a unit test, but it is quite interesting because it permits me to write assertion on number and text of SQL generated by NHibernate, a feature that is really interesting especially if you know that production database is quite big. To achieve this is really simple.

I wrote this simple test helper based on my infrastructure.

   1: public class InterceptNhQueriesHelper : ITestHelper

   2:  {

   3:      public const string nhQueries = "DFCDE96A-ADF7-4C46-A55B-219381364B7F";

   4:      private Dictionary<String, Level> _oldLevel = new Dictionary<string, Level>();


   6:      #region ITestHelper Members


   8:      public void FixtureSetUp(BaseTestFixture fixture)

   9:      {

  10:          ILogger loggerToForceInitializationOfLoggingSystem = IoC.Resolve<ILogger>();

  11:          var repository = LogManager.GetAllRepositories();

  12:          Log4NetLogEventSourceAppender interceptorAppender = new Log4NetLogEventSourceAppender();

  13:          foreach (var loggerRepository in repository)

  14:          {

  15:              Hierarchy hierarchy = (Hierarchy)loggerRepository;

  16:              if (hierarchy.GetAppenders()

  17:                      .Count(appender => appender.GetType() == typeof(Log4NetLogEventSourceAppender)) == 0)

  18:              {

  19:                  hierarchy.Root.AddAppender(interceptorAppender);

  20:                  hierarchy.RaiseConfigurationChanged(EventArgs.Empty);

  21:              }

  22:              _oldLevel[hierarchy.Name] = hierarchy.Root.Level;

  23:              hierarchy.Root.Level = Level.Debug;


  25:              var loggers = loggerRepository.GetCurrentLoggers();

  26:              foreach (var logger in loggers)

  27:              {

  28:                  Logger realLogger = logger as Logger;

  29:                  if (realLogger.Name.IndexOf("NHIBERNATE", StringComparison.InvariantCultureIgnoreCase) >= 0)

  30:                  {

  31:                      _oldLevel[realLogger.Name] = realLogger.Level;

  32:                      realLogger.Level = Level.Debug;

  33:                      if (!realLogger.Appenders.OfType<IAppender>().Any(appender => appender.GetType() == typeof(Log4NetLogEventSourceAppender)))

  34:                      {

  35:                          //non ho appender intercettori

  36:                          realLogger.AddAppender(interceptorAppender);

  37:                      }

  38:                  }

  39:              }


  41:              hierarchy.RaiseConfigurationChanged(EventArgs.Empty);

  42:          }


  44:          Log4NetLogEventSourceAppender.OnLog += Log4NetLogEventSourceAppender_OnLog;

  45:          loggerToForceInitializationOfLoggingSystem.Debug("TESTLOG DEBUG");

  46:          loggerToForceInitializationOfLoggingSystem.Info("TESTLOG Info");

  47:          loggerToForceInitializationOfLoggingSystem.Error("TESTLOG Error");

  48:      }


  50:      private BaseTestFixture currentFixture;

  51:      private List<String> SqlInstructions = new List<string>();


  53:      void Log4NetLogEventSourceAppender_OnLog(object sender, OnLog4NetLogEventArgs e)

  54:      {

  55:          if (e.LoggingEvent.LoggerName.Equals("nhibernate.sql", StringComparison.OrdinalIgnoreCase))

  56:          {

  57:              SqlInstructions.Add(e.LoggingEvent.MessageObject as string);

  58:          }

  59:      }


  61:      public void SetUp(BaseTestFixture fixture)

  62:      {

  63:          currentFixture = fixture;

  64:          fixture.SetIntoTestContext(nhQueries, SqlInstructions);

  65:          SqlInstructions.Clear();

  66:      }


  68:      public void TearDown(BaseTestFixture fixture)

  69:      {

  70:          currentFixture = null;

  71:      }


  73:      public void FixtureTearDown(BaseTestFixture fixture)

  74:      {

  75:          var repository = LogManager.GetAllRepositories();

  76:          foreach (var loggerRepository in repository)

  77:          {

  78:              Hierarchy hierarchy = (Hierarchy)loggerRepository;

  79:              hierarchy.Root.Level = _oldLevel[hierarchy.Name];


  81:              var loggers = loggerRepository.GetCurrentLoggers();

  82:              foreach (var logger in loggers)

  83:              {

  84:                  Logger realLogger = logger as Logger;

  85:                  if (realLogger.Name.IndexOf("NHIBERNATE", StringComparison.InvariantCultureIgnoreCase) >= 0 &&

  86:                      _oldLevel.ContainsKey(realLogger.Name))

  87:                  {


  89:                      realLogger.Level = _oldLevel[realLogger.Name];

  90:                  }

  91:              }

  92:              hierarchy.RaiseConfigurationChanged(EventArgs.Empty);

  93:          }

  94:      }


  96:      public int Priority

  97:      {

  98:          get { return 1; }

  99:      }


 101:      #endregion

 102:  }

this helpers seems complex, but basically it simply add during FixtureSetup an appender to log4net, this appender basically raises an event whenever it receives a log.

   1: public class Log4NetLogEventSourceAppender : AppenderSkeleton

   2:    {

   3:        private Object _syncRoot;


   5:        public Log4NetLogEventSourceAppender()

   6:        {

   7:            _syncRoot = new object();

   8:        }


  10:        /// <summary>

  11:        /// Occurs when [on log].

  12:        /// </summary>

  13:        public static event EventHandler<OnLog4NetLogEventArgs> OnLog;


  15:        protected override void Append(LoggingEvent loggingEvent)

  16:        {

  17:            EventHandler<OnLog4NetLogEventArgs> temp = OnLog;

  18:            if (temp != null)

  19:            {

  20:                lock (_syncRoot)

  21:                {

  22:                    temp(null, new OnLog4NetLogEventArgs(loggingEvent));

  23:                }

  24:            }

  25:        }


  27:    }


  29:    public class OnLog4NetLogEventArgs : EventArgs

  30:    {

  31:        public LoggingEvent LoggingEvent { get; private set; }


  33:        public OnLog4NetLogEventArgs(LoggingEvent loggingEvent)

  34:        {

  35:            LoggingEvent = loggingEvent;

  36:        }

  37:    }

This appender permits the helper to intercept all logs and since Nhibernate raise a log with name nhibernate.sql with the SQL Code whenever it raises a query to the database, the helper can filter for those kind of messages and store each query inside a standard String collection.

   1: public static class InterceptNhQueriesHelperMethods

   2: {

   3:     public static Int32 NhibernateQueryCount(this BaseTestFixtureWithHelper fixture)

   4:     {

   5:         return fixture.GetFromTestContext<List<String>>(InterceptNhQueriesHelper.nhQueries).Count;

   6:     }


   8:     public static List<String> NhibernateGetQueries(this BaseTestFixtureWithHelper fixture)

   9:     {

  10:         return fixture.GetFromTestContext<List<String>>(InterceptNhQueriesHelper.nhQueries);

  11:     }

  12: }

Now I can simply decorate my Test Fixture with a  specific attribute and let the magic happens.

   1: [InterceptNhQueries]

   2:    public class XxxFixture : Test.Utilities.BaseTestFixtureWithHelper

Inside a test I can use NhibernateQueryCount() to know the number of the queries issued by NH during the test and NhibernateGetQueries() to grab the whole list and assert on how NH interacted with the database during a test.

Gian Maria.

Custom XML Serialization

Another advantage of storing properties of entities into a state object based on a Dictionary, is the ability to easily serialize objects in custom formats. As an example I create an XML serializer that is capable to serialize an entity in a custom XML format.

I used this simple serializer to create a NHibernate User Type that permits me to save a child entity in a single XML column of SQL Server, a feature useful when you need to save objects which schema changes quite often and you do not want to keep database schema updated, or you need to store dynamic data into the DB. I now that all of you are screaming “USE NO SQL DB”, like Raven, but it is not simple to introduce new technologies into existing projects, and only to justify the need to save the 2% of objects.

Thanks to the custom serializer and the ability to do DeepCloning, writing such a User Type is really simple. First of all, I’ve implemented a method called EquivalentTo that permits me to compare two entities based on their state, this makes trivial writing the Equals Method of the UserType

bool IUserType.Equals(object x, object y)


    if (ReferenceEquals(x, y)) return true;

    if (x == null || y == null) return false;


    if (x is BaseEntity)

        return ((BaseEntity)x).IsEquivalentTo(y as BaseEntity);


    return x.Equals(y);


Same consideration for the IUserType.DeepCopy method, based on the Clone method of the base class. Saving and loading the object is just a matter of using the BaseEntity serialization methods.

public object NullSafeGet(System.Data.IDataReader rs, string[] names, object owner)


    Int32 index = rs.GetOrdinal(names[0]);

    if (rs.IsDBNull(index))


        return null;


    String databaseContent = (String)rs[index];

    return Deserialize(databaseContent);




internal Object Deserialize(String content)


    XElement element =  XElement.Parse(content);

    return element.DeserializeToBaseEntity();



public void NullSafeSet(System.Data.IDbCommand cmd, object value, int index)


    if (value == null || value == DBNull.Value)


        NHibernateUtil.String.NullSafeSet(cmd, null, index);




        NHibernateUtil.String.Set(cmd, Serialize(value), index);





internal String Serialize(Object obj)


    if (!(obj is BaseEntity))

        throw new ArgumentException("Only BaseEntity based entities could be serialized with this usertype", "obj");

    return (obj as BaseEntity).SerializeToXml().ToString();


The advantage of this approach, is that I have another base entity class called BaseExpandoEntity that permits to store into state object property by name, it is like a dynamic object, but I used it in .NET 3.5 where dynamics still does not exists. This kind of entity is clearly not really OOP, it is not well encapsulated, because you can set property of any name from external code and it is used mainly as a DataClass, just to store information in database without the need to be schema or class bounded. Now suppose to have a class called Father that has a property of type SpecificNotes, based on this BaseExpandoEntity and saved in database with the above User Type, you can write this code.

Father d1 = new Father () {...};

d1.SpecificNotes.SetProperty("Ciao", "mondo");

d1.SpecificNotes.SetProperty("Age", 80);


In the above code, the Father class has a property called SpecificNotes mapped as XML in database, I can store two new properties with the SetProperty and this is what is saved to database.






VALUES      (1,



             <SpecificNotes fname="Myproject.Entities.SpecificNotes, Myproject.Entities" ><Ciao>mondo</Ciao>

  <Age type="System.Int32">80</Age></SpecificNotes>' )

Now suppose you want to retrieve from the database all Father objects that have a SpecificNote with a  property named Ciao with value ‘mondo’, how could you issue the query since the object is stored as XML? The solution is creating a custom Criteria Operator. I do not want to bother you with the details, but the key method is something like this

public override NHibernate.SqlCommand.SqlString ToSqlString(

    NHibernate.ICriteria criteria, 

    ICriteriaQuery criteriaQuery, 

    IDictionary<string, NHibernate.IFilter> enabledFilters)


    string objectPropertyColumnName = criteriaQuery

        .GetColumnsUsingProjection(criteria, PropertyName)[0];


    StringBuilder criteriaText = new StringBuilder();




    criteriaText.Append(")[1]', 'nvarchar(max)')");

    switch (XmlCriterionParameters.CriteriaOperator)


        case CriteriaOperator.Equal:



        case CriteriaOperator.Like:

            criteriaText.Append(" like ");


        default :

            throw new NotSupportedException("Still not supported operator");



    criteriaText.AppendFormat("'{0}'", Value);

    return new SqlString(criteriaText.ToString());



In this example I’ve implemented only “=” and “like” operators, but it is enough for this sample. Now I can issue the following query.

Query query = Query.CreateXml("SpecificNotes", "Ciao", CriteriaOperator.Equal, "mondo");

var result = Repository.Father.GetByCriteria(query);

This snippet used a Query Model to specify the query, but as you can see the important aspect is that I’m able to create an XML criterion on the “SpecificNotes” sub object, where the expando property “Ciao” is Equal to the value “mondo”. Here is the query that was issued to the DB


FROM   Father this_

WHERE  this_.SpecificNotes.value('(/*/Ciao)[1]', 'nvarchar(max)') = 'mondo'

This is quite a primitive query, because of the /*/ that basically mean I’m searching for a property Ciao contained in any subobject, but you can modify your Custom Criterion to adapt the XPath to your need; the important aspect is that I’m now able to store and retrieve transparently my expando objects from a standard SQL server thanks to the great flexibility of NHibernate.

Gian Maria.