Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NHibernate - how to delete an item from many-to-many relationship?

I've following mapping for two tables having a Many-to-Many relationship between them. How do I delete an entry from the mapping table, which is 'ProjectUser' in my case?

public ProjectMap()
{
    Id(x => x.Id);
    Map(x => x.ProjectName);
    Map(x => x.Description);
    References<User>(x => x.Owner);
    HasManyToMany(x => x.Users)
        .Cascade.SaveUpdate()
        .Table("ProjectUser")
        .Not.LazyLoad();
}


public UserMap()
{
    Id(x => x.Id);
    Map(x => x.FirstName);
    Map(x => x.LastName);
    Map(x => x.UserName);
    HasManyToMany(x => x.Projects)
        .Cascade.SaveUpdate()
        .Inverse()
        .Table("ProjectUser")
        .Not.LazyLoad();
}

EDIT: changed Cascade to SaveUpdate as suggested in answers. Here is the code I use to commit data to SQLite database.

using (var trans = session.BeginTransaction())
{
    var existingUsers = project.Users.ToList();
    foreach (var item in existingUsers)
    {
        if (selectedUsers.Count(x => x.Id == item.Id) == 0)
            project.Users.RemoveAt(project.Users.IndexOf(item));
    }
    session.SaveOrUpdate(project); // This fixed the issue
    session.Flush();
    foreach (var item in selectedUsers)
    {
        if (project.Users.Count(x => x.Id == item.Id) == 0)
        {
            project.AddUser(session.Get<User>(item.Id));
        }
    }
    session.SaveOrUpdate(project);
    session.Flush();
    trans.Commit();
}

// Add user code in Project class
public virtual void AddUser(User userToAdd)
{
    if (this.Users == null)
        this.Users = new List<User>();
    userToAdd.Projects.Add(this);
    this.Users.Add(userToAdd);
}

Whenever I try to save/update I'm getting the following error:

a different object with the same identifier value was already associated with the session: 10, of entity: Models.Project

EDIT2: Should use session.SaveOrUpdate(project) and session.Flush() to avoid error stated above.

like image 554
Raj Avatar asked Feb 16 '12 17:02

Raj


1 Answers

If you only want to remove the ProjectUser entry and not actually delete the entity on the other side you need to change from Cascade.All() to Cascade.SaveUpdate().

Currently if you removed a user from a project and saved the project it would delete the ProjectUser entry and the User object.

like image 135
Cole W Avatar answered Oct 21 '22 21:10

Cole W