After updating to nHibernate 4, cannot use ManyToMany Mappings. Could not determine type

254 Views Asked by At

After updating to nHibernate (4.0.2.4000 via nuget), the many to many mappings that previously worked now cause mapping exception "Could not determine type for: nHibernateManyToMany.IRole, nHibernateManyToMany, for columns: NHibernate.Mapping.Column(id)"

Seems to be only for many to many, and when the List is a interface (i.e. List<Role> vs List<IRole>).

Example code that now fails:

class Program
{
    static void Main(string[] args)
    {
        var configuration = new Configuration().SetProperty(Environment.ReleaseConnections, "on_close")
                                               .SetProperty(Environment.Dialect, typeof(SQLiteDialect).AssemblyQualifiedName)
                                               .SetProperty(Environment.ConnectionDriver, typeof(SQLite20Driver).AssemblyQualifiedName)
                                               .SetProperty(Environment.CollectionTypeFactoryClass, typeof(DefaultCollectionTypeFactory).AssemblyQualifiedName)
                                               .SetProperty(Environment.CommandTimeout, "0");

        var mapper = new ModelMapper();

        mapper.AddMappings(new[] { typeof(EmployeeMapping), typeof(RoleMapping) });

        var hbmMapping = mapper.CompileMappingForAllExplicitlyAddedEntities();

        hbmMapping.autoimport = false;

        configuration.AddMapping(hbmMapping);

        // this line will fail
        var factory = configuration.BuildSessionFactory();
    }
}

public class Employee
{
    public virtual int Id { get; set; }
    public virtual List<IRole> Roles { get; set; }
}

public interface IRole
{
    int Id { get; set; } 
    string Description { get; set; }
}

public class Role : IRole
{
    public virtual int Id { get; set; }
    public virtual string Description { get; set; }
}

public class EmployeeMapping : ClassMapping<Employee>
{
    public EmployeeMapping()
    {
        Id(c => c.Id, x =>
        {
            x.Type(NHibernateUtil.Int32);
            x.Generator(Generators.Identity);
            x.Column("EmployeeId");
        });

        Bag(x => x.Roles, m =>
        {
            m.Table("EmployeeRole");
            m.Key(km =>
            {
                km.Column("EmployeeId");
                km.NotNullable(true);
                km.ForeignKey("FK_Role_Employee");
            });
            m.Lazy(CollectionLazy.Lazy);
        }, er => er.ManyToMany(m =>
        {
            m.Class(typeof(Role));
            m.Column("RoleId");
        }));
    }
}

public class RoleMapping : ClassMapping<Role>
{
    public RoleMapping()
    {
        Id(c => c.Id, x =>
        {
            x.Type(NHibernateUtil.Int32);
            x.Generator(Generators.Identity);
            x.Column("RoleId");
        });

        Property(x => x.Description, c =>
        {
            c.Length(50);
            c.NotNullable(true);
        });
    }
}

Any help or suggestions about where we could look for details on how this has changed since v3 would be appreciated.

1

There are 1 best solutions below

0
On

Turned out to be a bug in nHibernate.

A pull request has been submitted here https://github.com/nhibernate/nhibernate-core/pull/385