nhibernatenhibernate-mapping-by-code

Mapping-By-Code ignores Column Name in BagPropertyMapper


I'm encountering a problem, and I think it's an NHibernate defect.

My Database Schema, containing a simple Parent-Child mapping:

  TABLE Company
  (
       ID BIGINT PRIMARY KEY
  )

  TABLE CompanyMailRecipient
  (
       ID              BIGINT PRIMARY KEY IDENTITY(1, 1),
       Company_ID      BIGINT NOT NULL FOREIGN KEY REFERENCES Company(id),
       Name            VARCHAR(MAX),
       EmailAddress    VARCHAR(MAX),
       DestinationType TINYINT
  )

My classes. Note that the CompanyMailRecipient table has a column called EmailAddress, but my MailRecipient class has a column called Address.

public enum MessageDestinationType
{
    Normal = 1,
    CC = 2,
    BCC = 3
}

public class MailRecipient
{
    public virtual string Name {get; set }
    public virtual string Address {get; set; } // Different name to the column!
    public virtual MessageDestinationType DestinationType {get; set;}
} 

public class MailConfiguration
{
    private Lazy<IList<MailRecipient>> _recipients = new Lazy<IList<MailRecipient>>(() => new List<MailRecipient>());
    public virtual IList<MailRecipient> Recipients
    {
        get
        {
            return _recipients.Value;
        }
        set
        {
            _recipients = new Lazy<IList<MailRecipient>>(() => value);
        }
    }
}

public class Company
{
     public virtual long Id { get; set; }
     public virtual MailConfiguration MailConfiguration { get; set; }
}

The mapping code

mapper.Class<Company>(
       classMapper =>
       {
           classMapper.Table("Company");
           classMapper.Component(
                 company => company.MailConfiguration,
                 componentMapper =>
                 {
                      componentMapper.Bag(mc => mc.Recipients,
                          bagPropertyMapper =>
                          {
                              bagPropertyMapper.Table("CompanyMailRecipient");
                               bagPropertyMapper.Key(mrKeyMapper =>
                               {
                                   mrKeyMapper.Column("Company_Id");
                               });
                           },
                           r => r.Component(
                              mrc =>
                              {

                                  mrc.Property
                                  (
                                     mr => mr.Name, 
                                     mrpm => mrpm.Column("Name")
                                  );
                                  /*****************************/
                                  /* Here's the important bit  */
                                  /*****************************/
                                  mrc.Property
                                  (
                                     mr => mr.Address, 
                                     mrpm => mrpm.Column("EmailAddress");
                                  );
                                  mrc.Property
                                  (
                                      mr => mr.DestinationType, 
                                      mrpm => mrpm.Column("DestinationType")
                                  );
                              };
                           )
                      );
                 }
       }

Now here's the problem: when I attempt to query a Company, I get the following error (with significant parts in bold)

NHibernate.Exceptions.GenericADOException : could not initialize a collection: [Kiosk.Server.Entities.Company.MailConfiguration.Recipients#576][SQL: SELECT recipients0_.Company_Id as Company1_0_, recipients0_.Name as Name0_, recipients0_.Address as Address0_, recipients0_.DestinationType as Destinat4_0_ FROM CompanyMailRecipient recipients0_ WHERE recipients0_.Company_Id=?] ----> System.Data.SqlClient.SqlException : Invalid column name 'Address'. at NHibernate.Loader.Loader.LoadCollection(ISessionImplementor session, Object id, IType type)

But, if I change my C# code so my MailRecipient class has a propery called EmailAddress instead of Address, everything works.

It's like NHibernate is ignoring my column mapping.

Is this an NHibernate bug, or am I missing something?

The version of NHibernate I'm using is 4.0.4.4.


The example above has a one-to-many component hanging off a component that hangs off the entity.

I found that if I removed a layer of inderection, and had my one-to-many component hanging off the entity directly, then the column name takes effect.


Solution

  • Yes, this was indeed a bug in NHibernate.

    I issued a fix as a pull request which has now been merged into the codebase. It should be in a release after 4.1.1.