The 'child' object hasn't been added to the 'parent's Children
collection in the first example, so there's nothing for NHibernate to
cascade the delete onto (Children is empty). When you retrieve it
from the DB in the 2nd piece of code the Children collection is
populated and so NHibernate can cascade the deletion. So yes, it's a
bug, but not in NH :). FWIW, when I have a bidirectional parent/child
relationship I usually code the child's constructor to take the Parent
object as a parameter:
class Child {
protected Child() {} // Required
public Child(Parent myParent) {
if(myParent != null) {
this.Parent = myParent;
myParent.Children.Add(this);
} // else throw exception if the parent
is mandatory
}
Pete
From: [email protected] [mailto:[email protected]] On
Behalf Of Mouhong Lin
Sent: 19 September 2012 11:27
To: [email protected]
Subject: [nhusers] Save and delete (cascade delete) in the same session
will fail
Hi guys,
This is my model:
public class Category
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual Category Parent { get; set; }
public virtual IList<Category> Children { get; protected set; }
public Category()
{
Children = new List<Category>();
}
}
This is the mapping:
class CategoryMap : ClassMapping<Category>
{
public CategoryMap()
{
Table(typeof(Category).Name);
this.HighLowId(c => c.Id);
Property(c => c.Name);
ManyToOne(c => c.Parent, m => m.Column("ParentId"));
Bag(c => c.Children, m =>
{
m.Key(k => k.Column("ParentId"));
m.Cascade(Cascade.All | Cascade.DeleteOrphans);
m.Inverse(true);
},
m => m.OneToMany());
}
}
This is the database script:
create table Category
(
Id int not null,
Name nvarchar(50) not null,
ParentId int null,
constraint PK_Category primary key (Id),
constraint FK_Category_ParentId foreign key (ParentId)
references Category(Id)
)
This is the test code:
var parent = new Category { Name = "Category 1" };
var child = new Category
{
Name = "Category 2",
Parent = parent
};
using (var session = Database.OpenSession())
{
using (var tran = session.BeginTransaction())
{
session.Save(parent);
session.Save(child);
tran.Commit();
}
using (var tran = session.BeginTransaction())
{
session.Delete(parent);
tran.Commit(); // Exception:
}
}
The above code will cause this exception:
The DELETE statement conflicted with the SAME TABLE REFERENCE constraint
"FK_Category_ParentId". The conflict occurred in database "Test", table
"dbo.Category", column 'ParentId'. The statement has been terminated."
But if I delete the parent category in a NEW session, it will work:
var parent = new Category { Name = "Category 1" };
var child = new Category
{
Name = "Category 2",
Parent = parent
};
using (var session = Database.OpenSession())
{
using (var tran = session.BeginTransaction())
{
session.Save(parent);
session.Save(child);
tran.Commit();
}
}
using (var session = Database.OpenSession())
{
parent = session.Get<Category>(parent.Id);
using (var tran = session.BeginTransaction())
{
session.Delete(parent);
tran.Commit();
}
}
Is this a bug? I'm using NHibernate.3.3.1.4000. Thanks :)
--
You received this message because you are subscribed to the Google
Groups "nhusers" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/nhusers/-/9D6NH4rWi9MJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en.
--
You received this message because you are subscribed to the Google Groups
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en.