I'm using NHibernate mapping by code to map relationships. In this case I map users to roles to privileges. Users and roles are in a n:m relationship, same for roles and privileges. The SQL DB is SQL Server.
If I remove the n:m relationshop from my code between roles and privileges, my code works. If it is there, I get the following MappingException
:
Could not determine type for:
Dtp.Entities.AppPrivilege, Dtp.Entities, for columns: NHibernate.Mapping.Column(id)
I can't find the source of the difference, since the same relationshop between users and roles works without a hitch. Can anyone shed a light on this problem please?
The precise part which produces the error (it goes away if commented out) is the Bag for AppRole.AppPrivileges
.
~~~ Table ~~~
AppUserId, uniqueidentifier, not null
//some omitted properties
~~~ Entity ~~~
public class AppUser {
public virtual Guid AppUserId { get; set; }
//some omitted properties
public virtual IList<AppRole> AppRoles { get; set; }
}
~~~ Mapping ~~~
public class AppUserMap : ClassMapping<AppUser>
{
public AppUserMap()
{
Table("AppUser");
Schema("dbo");
Lazy(true);
Id(x => x.AppUserId, map => map.Generator(Generators.GuidComb));
//some omitted properties
Bag(x => x.AppRoles,
colmap => {
colmap.Cascade(Cascade.None);
colmap.Table("AppUser_AppRole");
colmap.Key(x => x.Column("AppUserId"));
},
map => map.ManyToMany(many => many.Column("AppRoleId")));
}
}
~~~ Table ~~~
AppUserId, uniqueidentifier, not null
AppRoleId, uniqueidentifier, not null
~~~ Table ~~~
AppRoleId, uniqueidentifier, not null
//some omitted properties
~~~ Entity ~~~
public class AppRole{
public virtual Guid AppRoleId { get; set; }
//some omitted properties
public virtual IList<AppUser> AppUsers { get; set; }
public virtual IList<AppPrivilege> AppPrivileges { get; set; }
}
~~~ Mapping ~~~
public class AppRoleMap : ClassMapping<AppRole> {
public AppRoleMap()
{
Table("AppRole");
Schema("dbo");
Lazy(true);
Id(x => x.AppRoleId, map => map.Generator(Generators.GuidComb));
//some omitted properties
Bag(x => x.AppUsers,
colmap => {
colmap.Cascade(Cascade.None);
colmap.Table("AppUser_AppRole");
colmap.Key(x => x.Column("AppRoleId"));
},
map => map.ManyToMany(many => many.Column("AppUserId")));
//The following definition produces the bug.
Bag(x => x.AppPrivileges,
colmap => {
colmap.Cascade(Cascade.None);
colmap.Table("AppRole_AppPrivilege");
colmap.Key(x => x.Column("AppRoleId"));
},
map => map.ManyToMany(many => many.Column("AppPrivilegeId")));
}
}
~~~ Table ~~~
AppRoleId, uniqueidentifier, not null
AppPrivilegeId, uniqueidentifier, not null
~~~ Table ~~~
AppPrivilegeId, uniqueidentifier, not null
//some omitted properties
~~~ Entity ~~~
public class AppPrivilege {
public virtual Guid AppPrivilegeId { get; set; }
//some omitted properties
public virtual IList<AppRole> AppRoles { get; set; }
}
~~~ Mapping ~~~
public class AppPrivilegeMap: ClassMapping<AppPrivilege> {
public AppPrivilegeMap()
{
Table("AppPrivilege");
Schema("dbo");
Lazy(true);
Id(x => x.AppPrivilegeId, map => map.Generator(Generators.GuidComb));
//some omitted properties
Bag(x => x.AppRoles,
colmap => {
colmap.Cascade(Cascade.None);
colmap.Table("AppRole_AppPrivilege");
colmap.Key(x => x.Column("AppPrivilegeId"));
},
map => map.ManyToMany(many => many.Column("AppRoleId")));
}
}
The answer to this problem cannot be found in the files above. I just forgot to add the AppPrivilegeMap
to the ModelMapper
during NHibernateHelper.OnConfigure()
.
Now the last task is to find out where to put the .Inverse(true)
, so serializing an object won't result in an exception because of circular reference.