We have tried to upgrade from nhibernate 3.1 to 3.3 and now we get a lot of
those exceptions, they come from the mapping that we use for the one to
many relation, which are not nullable foreign keys.
For example we have a many to many relation between the User table and Role
table with additional information in the RoleToUser table, so it is also
mapped as an entity:
public class User
{
public User() { Roles = new List<RoleUser>(); }
public virtual Guid Id { get; set; }
public virtual string Username { get; set; }
public virtual IList<RoleUser> Roles { get; set; }
}
public class Role
{
public Role() { Users = new List<RoleUser>(); }
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<RoleUser> Users { get; set; }
}
public class RoleUser
{
public virtual Guid Id { get; set; }
public virtual User User { get; set; }
public virtual Role Role { get; set; }
}
public class UserMap : ClassMap<User>
{
public UserMap()
{
Id(x => x.Id).GeneratedBy.GuidComb().UnsavedValue(Guid.Empty.ToString());
Map(x => x.Username).Length(20).Not.Nullable();
HasMany(x => x.Roles)
.Not.KeyNullable() //This is causing the problem
.Cascade.SaveUpdate();
}
}
public class RoleMap : ClassMap<Role>
{
public RoleMap()
{
Id(x => x.Id).GeneratedBy.GuidComb().UnsavedValue(Guid.Empty.ToString());
Map(x => x.Name).Length(32).Not.Nullable();
HasMany(x => x.Users)
.Not.KeyNullable() //This is causing the problem
.Cascade.SaveUpdate();
}
}
public class RoleUserMap : ClassMap<RoleUser>
{
public RoleUserMap()
{
Table("RoleToUser");
Id(x => x.Id).GeneratedBy.GuidComb().UnsavedValue(Guid.Empty.ToString());
References(x => x.User)
.Not.Nullable()
.Cascade.None();
References(x => x.Role)
.Not.Nullable()
.Cascade.None();
}
}
Now if we try to add an existing Role to an existing User , this
means insert a new entry in the RoleToUser table, nhibernate throws the
exception "not-null property references a null or transient value":
static void Test04()
{
var user = Session.Query<User>().First();
var role = Session.Query<Role>().First();
user.Roles.Add(new RoleUser() { User = user, Role = role });
Session.SaveOrUpdate(user);
Session.Flush();
}
If we comment the ".Not.KeyNullable()" in the mapping it works but this
mapping was exactly to prevent nhibernate to try to set to null foreign
keys that can't be null, more over before with the Not.KeyNullable()
nhibernate was sending only one insert query to the DB, now if we
remove the Not.KeyNullable() nhibernate send two queries to the DB an
insert and then an update, which is complete useless!
exec sp_executesql N'INSERT INTO dbo.RoleToUser (User_id, Role_id, Id)
VALUES (@p0, @p1, @p2)',N'@p0 uniqueidentifier,@p1 uniqueidentifier,@p2
uniqueidentifier',@p0='B05D6CFD-E571-46EA-B854-9C5300F9D091',@p1='59B05DEC-D8B2-4FEE-ABEB-9C5300F9D067',@p2='BF53DBFD-C285-445F-8015-A20E011203EB'
exec sp_executesql N'UPDATE dbo.RoleToUser SET User_id = @p0 WHERE Id =
@p1',N'@p0 uniqueidentifier,@p1
uniqueidentifier',@p0='B05D6CFD-E571-46EA-B854-9C5300F9D091',@p1='BF53DBFD-C285-445F-8015-A20E011203EB'
We didn't find any information about breaking changes about this mapping,
is it a bug? Otherwise how we have to change the mappings to have the same
behavior as before?
--
You received this message because you are subscribed to the Google Groups
"nhusers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/nhusers.
For more options, visit https://groups.google.com/groups/opt_out.