views:

152

answers:

1

My Domain auto mapping was working but now as I updated my NHibernate stack I'm getting mapping exception when Session Factory is building the Configuration:

"Can't figure out what the other side of the many-to-many property 'Users' should be."

The exception is thrown on a many to many map

The whole stack trace is this one:

at FluentNHibernate.Cfg.FluentConfiguration.BuildConfiguration() in
c:\hornget.horn\orm\fluentnhibernate\Working-2.1\src\FluentNHibernate\Cfg\FluentConfiguration.cs:line 119 at
WebApplication1.NHibernateManager.SessionFactoryManager.BuildConfiguration(AutoPersistenceModel
persistanceModel) in
C:\WebProgramming\Projects\WebApplication1\WebApplication1\NHibernateManager\SessionFactoryManager.cs:line 116 at
WebApplication1.NHibernateManager.SessionFactoryManager.GetSessionFactory() in
C:\WebProgramming\Projects\WebApplication1\WebApplication1\NHibernateManager\SessionFactoryManager.cs:line 71 at
WebApplication1.NHibernateManager.SessionManager.CloseSession() in
C:\WebProgramming\Projects\WebApplication1\WebApplication1\NHibernateManager\SessionManager.cs:line 47 at
WebApplication1.Global.Application_EndRequest(Object sender, EventArgs e) in
C:\WebProgramming\Projects\WebApplication1\WebApplication1\Global.asax.cs:line
36 at
System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

The Question is how to handle the many to many relationship properly using automapping.
Note: the mapping was working before i updated the NHibernate/FluentNHibernate stack...

Relevant definitions are pasted below:

The Domain classes (in Dll 1):

public class User : Entity  
{  
// ... removed properties  

    public virtual IList<Role> Roles { get; protected set; }//has many  

// ...  removed methods   
}

public class Role : Entity
{
// ... removed properties  

    public virtual IList<User> Users { get; protected set; }//has many

// ... removed methods  
}

Entity class (in DLL 2):

/// <summary>
/// Base Entity deffinition
/// </summary>
public abstract class Entity : IEquatable<Entity>
{
    private int _Id = 0;
    public virtual int Id { get { return _Id; } }

    //... removed methods  
}

Conventions:

public class PrimaryKeyConvention : IIdConvention
{
    public void Apply(IIdentityInstance instance)
    {
        instance.Column(instance.EntityType.Name + "Id");
        instance.GeneratedBy.HiLo("100");
        instance.Access.ReadOnlyPropertyThroughPascalCaseField(PascalCasePrefix.Underscore);

    }
}


public class ClassConvention : IClassConvention
{
    public void Apply(IClassInstance instance)
    {
        instance.Table(Inflector.Pluralize(instance.EntityType.Name));
        instance.LazyLoad();
        instance.Cache.NonStrictReadWrite();
    }
}  

Many to Many Convention:

public class ManyToManyConvention : IHasManyToManyConvention
{
    public void Apply(IManyToManyCollectionInstance instance)
    {
        if (instance.OtherSide == null)
        {
            instance.Table(
                string.Format(
                    "{0}To{1}",
                    Inflector.Pluralize(instance.EntityType.Name),
                    Inflector.Pluralize(instance.ChildType.Name)));
            instance.Cascade.AllDeleteOrphan();
        }
        else
        {
            instance.Inverse();
        }
    }

}

Model:

 var persistanceModel = AutoMap.AssemblyOf<DataModelPaceholder>()
        .AddEntityAssembly(typeof(Entity).Assembly)
        .Conventions.AddFromAssemblyOf<ClassConvention>()
        .UseOverridesFromAssemblyOf<DataModelPaceholder>()
        .Setup(s =>
        {
            s.SubclassStrategy = t => SubclassStrategy.JoinedSubclass;
            s.IsComponentType = type => type == typeof(MoneyComponent);
        })
        .IgnoreBase<Entity>()
        .IgnoreBase<EntityAudit>()
        //.IncludeBase<Product>()
        .Where
        (
            type => typeof(Entity).IsAssignableFrom(type) && !type.IsAbstract
        );
A: 

Do you have a junction table named UsersToRoles with the appropriately named columns as per AutoMap default conventions? e.g. User_id,Role_id ?

Sky Sanders
csizo
It seems that I had some version problems with the fluent-nhibernate component... It was picking up version 2.1. :(
csizo
so, it was an id convention problem?
Sky Sanders
It was an Id convention problem but due to fluentnhibernate versioning. I updated fluentnhibernate using hornget and there were some problem with the build... The version it produced was not handling the many-many convention properly.My conclusion is to double check the output of hornget.
csizo