I have a few objects.
Project Object - this represents a basic project
ProjectDependency Object - this is mapping object that maps one project to another project (the dependent project). See the nhibernate relationships:
here is the ProjectDependencies mapping class:
public class ProjectDependencyMap
{
public ProjectDependencyMap()
{
References(x => x.Project).Not.Nullable().Fetch.Join();
References(x =>.DependencyProject).Not.Nullable().Column("DependencyProjectId").Fetch.Join();
}
}
and here is the project map file:
public class ProjectMap
{
public ProjectMap()
{
HasMany(x => x.ProjectDependencies).AsBag().Inverse().Cascade.AllDeleteOrphan().Fetch.Select().BatchSize(80);
HasMany(x => x.ProjectDependentOf).KeyColumn("DependentProjectId").AsBag().Inverse().Cascade.AllDeleteOrphan().Fetch.Select().BatchSize(80);
}
}
normally this works fine but sometimes when i go to delete a project using:
var project = Model.GetProject(id);
Repository.Delete(project);
Repository.Commit()
I get this error:
deleted object would be re-saved by cascade (remove deleted object from associations)[ProjectDependency#324]
Can someone help clarify what the issue is here and if the way i am using the mapping above is incorrect
For the purposes of this answer, I'm assuming that Project.ProjectDependencies
is the other side of the ProjectDependency.Project
relationship, not the ProjectDependency.Dependent
relationship. (now say that 3 times fast)
Consider the following objects:
var projectA = new Project();
var projectB = new Project();
var dep1 = new ProjectDependency
{
Project = projectA,
Dependent = projectB
};
projectA.ProjectDependencies.Add(dep1);
... and save them all to the database. Now, let's delete one.
session.Delete(projectA);
Everything works fine. NHibernate cascades the delete across the ProjectDependencies
collection, so projectA
and dep1
are both deleted. projectB
is left in the database.
OK, let's reset. Let's start over with projectA
, projectB
, and dep1
in the database. Additionally, let's add these:
var projectC = new Project();
var dep2 = new ProjectDependency
{
Project = projectC,
Dependent = projectA
};
projectC.ProjectDependencies.Add(dep2);
What happens when we delete projectA
now?
session.Delete(projectA);
Everything tries to proceed as before. dep1
will be deleted by the cascade. However, there's nothing there to clean up dep2
, hence the error. dep2
still has a reference to projectA
, which we are trying to delete.
The solution suggested by the error message is to clean up those relationships before trying to delete the entity. However, how are you going to do this? Starting from projectA
, how do we find dep2
and projectC
to clean them up?
Two options:
session.Query<ProjectDependency>().Where(x => x.Dependent == projectA)
, then manually clean up the relationships.Project
:HasMany(x => x.DependentProjects)
.KeyColumn("DependentProjectId")
.AsBag()
.Inverse()
.Cascade.AllDeleteOrphan();
... and then NHibernate would take care of the cleanup for you.