I’m having some trouble with NHibernate, while trying to remove an object describing a relation between rows in two different tables – a many to many relation.
I’ve got Users, CourseInstances and UserRoles, where Users are mapped to certain course instances. Users can be a part of many course instances, and course instances have many users attending.
All this is mapped by Fluent.
User: HasMany(x => x.UserRoles).KeyColumn("UserId");
CourseInstance: HasMany(x => x.UserRoles);
UserRole:
References(x => x.User).Column("UserId");
References(x => x.CourseInstance).Column("InstanceId");
The above describes how they are mapped together, its a fairly simple mapping, though each have some additional information but nothing related to each other.
I try to run the following code:
using (var session = factory.OpenSession())
{
var user = session.Get<NData.User>(userId);
if (user == null)
throw new FaultException(new FaultReason("No user with that id found."));
var instance = session.Get<NData.CourseInstance>(courseInstanceId);
if (instance == null)
throw new FaultException(new FaultReason("No course instance with that id found."));
var userrole = session.CreateQuery(string.Format("from UserRole where User.Id = {0} and CourseInstance.Id = {1} and Role.Role = {2}", userId, courseInstanceId, role)).UniqueResult<NData.UserRole>();
if (userrole == null)
throw new FaultException(new FaultReason("That user is not present in that course instance with that role."));
instance.UserRoles.Remove(userrole);
user.UserRoles.Remove(userrole);
session.Delete(userrole);
session.Update(user);
session.Update(instance);
session.Flush();
}
However, Flush throws an exception:
could not delete collection rows: [Giraffe.WebService.NHibernate.Data.User.UserRoles#8][SQL: UPDATE UserRoles SET UserId = null WHERE UserId = @p0 AND Id = @p1]
Why is it trying to UPDATE the role first?
Because you’re doing
user is a managed entity that NHibernate will update, just as you’re seeing.