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.
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.
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.