Saan
Saan

Reputation: 544

Error: fluent NHibernate mapping which references mapping in different assembly

My company has multiple sites which reference the same DB and Core library of code. Then we have a CMS which manages the data.

In the Core library I have a Site class which holds a bunch of basic info about each site. This is the fluent mapping I have for it.

using Core.Model;  // Where Site class exists

namespace Core.Repository.NHibernate.Mappings
{
    public class SiteMapping : ClassMap<Site>
    {
        public SiteMapping()
        {
            Table("f_site");
            Id(x => x.Id, "f_site_id").GeneratedBy.Identity();
            Map(x => x.Domain, "domain_name").Not.Nullable();
        }
    }
}

As part of the CMS, we keep a log of who edited what and when. But I want to only have a reference to the Log class and mapping in the CMS, rather than in my core code, as people can only edit info via the CMS.

Here is my current fluent mapping to the Log class, which referneces the Site class.

using Core.Model; // where Site class exists
using Cms.Model; // where Log and CmsUser classes exists

namespace Cms.Repository.NHibernate.Mappings
{
    public class LogMapping : ClassMap<Log>
    {
        public LogMapping()
        {
            Table("f_log");
            Id(x => x.Id, "f_log_id").GeneratedBy.Identity();
            Map(x => x.Message, "message");
            Map(x => x.LogType, "d_log_type_id").CustomType<LogType>();
            Map(x => x.LogOperation, "d_log_operation_id").CustomType<LogOperation>();
            Map(x => x.Date, "log_date");

            References<Site>(x => x.Site, "f_site_id")
                .ForeignKey("f_site_id")
                .Cascade.None();

            References<CmsUser>(x => x.User, "userId")
                .ForeignKey("userId")
                .Cascade.None();
        }
    }
}

In theory this works great, but the Log mapping errors with the following

Cms.Tests.Repository.NHibernate.Repository.TestLogRepository.TestLogMappings:
StructureMap.StructureMapException : StructureMap Exception Code:  207
Internal exception while creating Instance 'e46153a3-2bfe-4279-8749-a42d7a6dd10c' of PluginType Core.Repository.NHibernate.SessionStorage.ISessionContainer`1[[HbmCms.Repository.NHibernate.Mappings.Config.LogMapping, Cms.Repository.NHibernate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Core.Repository.NHibernate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.  Check the inner exception for more details.
  ----> StructureMap.StructureMapException : StructureMap Exception Code:  207
Internal exception while creating Instance '9e72c2ff-e3f4-4b54-9f34-3422a7b982a7' of PluginType Core.Repository.NHibernate.SessionStorage.ISessionFactoryContainer`1[[Cms.Repository.NHibernate.Mappings.Config.LogMapping, Cms.Repository.NHibernate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].  Check the inner exception for more details.
  ----> FluentNHibernate.Cfg.FluentConfigurationException : An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.


  ----> NHibernate.MappingException : An association from the table f_log refers to an unmapped class: Core.Model.Site

Does anyone have any idea how to get my CMS mapping to reference the Core Site mapping? This is the first bit of code that is getting a mapping across two projects, but its something that we'll be doing a fair bit of, as lots of stuff you only look at and do in the CMS. I don't really want to put the CMS only code into the Core library if i can avoid it.

Thanks for the help

Sandra

Upvotes: 0

Views: 2446

Answers (1)

David R. Longnecker
David R. Longnecker

Reputation: 3157

An 'unmapped class' error usually stems from the Configuration not having that ClassMap recorded.

In your FluentConfiguration, you probably have something similar to:

.Mappings(m => m.FluentMappings
                .AddFromAssemblyOf<T>())

It appears that your two ClassMaps (at least those mentioned in the post) are in different assemblies. You can specify multiple assemblies with:

.Mappings(m => m.FluentMappings
                .AddFromAssemblyOf<T1>()
                .AddFromAssemblyOf<T2>())

To see exactly what is being mapped, you can add

.Diagnostics(d => d.Enable().OutputToConsole())

to your FluentConfiguration and it will return the class maps, the conventions applied to them and why/why not they were valid.

Upvotes: 5

Related Questions