NHIbernate_StackOverflow

3
sign up log in tour help stack overflow careers Take the 2minute tour × Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required. How to delete child object in NHibernate? I have a parent object which has a one to many relationship with an IList of child objects. What is the best way to delete the child objects? I am not deleting the parent. My parent object contains an IList of child objects. Here is the mapping for the one to many relationship: <bag name="Tiers" cascade="all"> <key column="mismatch_id_no" /> <one‐to‐many class="TGR_BL.PromoTier,TGR_BL"/> </bag> If I try to remove all objects from the collection using clear(), then call SaveOrUpdate(), I get this exception: System.Data.SqlClient.SqlException: Cannot insert the value NULL into column If I try to delete the child objects individually then remove them from the parent, I get an exception: deleted object would be re‐saved by cascade This is my first time dealing with deleting child objects in NHibernate. What am I doing wrong? edit: Just to clarify I'm NOT trying to delete the parent object, just the child objects. I have the relationship set up as a one to many on the parent. Do I also need to create a manytoone relationship on the child object mapping? nhibernate edited Nov 19 '08 at 19:51 asked Nov 19 '08 at 17:33 Mark Struzinski 12.7k 25 82 113 6 Answers You are getting the first error because, when you remove the items from the collection, NHibernate's default mode of operation is to simply break the association. In the database, NHibernate tries to set the foreign key column on the child row to null. Since you do not allow nulls in that column, SQL Server raises the error. Clearing the collection will not necessarily delete the child object, but one way to do so is to set cascade=alldeleteorphan. This informs NHibernate that it should delete the newly orphaned rows instead of setting the foreign key column. You are getting the second error because when you call SaveOrUpdate NHibernate first deletes all of the child objects. Then, because neither relationship is marked as inverse, NHibernate also tries to set the foreign key column in your child table to null. Since the rows have already been deleted, you receive the second error. You need to set inverse=true on one side of your relationship to fix this. This is usually done on the one (primary key or parent) side. If you do not do this, NHibernate will make the appropriate updates for each side of the relationship. Unfortunately, running two updates is not the appropriate thing to do. You should always mark one side of your relationships as the inverse side. Depending on how you code, you may or may not need to use cascading. If you want to take advantage of one shot deletes as you are trying to do using Clear(), you need to define your cascade. edited Jan 2 '09 at 16:23 answered Nov 19 '08 at 18:21 Chuck 6,634 2 16 18 Just to clarify I've only got the relationship defined on the Parent object right now. I've tried to set the cascade on that object to "all" and "alldeleteorphan" with the same results both times. You mean I need to define a manytoone relationship on the child object as well? Mark Struzinski Nov 19 '08 at 18:28 And in this case does inverse="true" belong on the parent or child object? Mark Struzinski Nov 19 '08 at 18:29 2 it belong to the class that does not hold the foreign key... usually the parent. pmlarocque Dec 1 '08 at 18:33 Thanks for this explanation, again an inverse issue caught me out, and seeing it explained like this really

description

NHibernate Cascade Delete answer

Transcript of NHIbernate_StackOverflow

Page 1: NHIbernate_StackOverflow

06/04/2015 How to delete child object in NHibernate? ­ Stack Overflow

http://stackoverflow.com/questions/302720/how­to­delete­child­object­in­nhibernate 1/3

        

sign up log in tour help  stack overflow careers

 Take the 2­minute tour ×Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, noregistration required.

How to delete child object in NHibernate?

I have a parent object which has a one to many relationship with an IList of child objects. What is the best way to delete the child objects? Iam not deleting the parent. My parent object contains an IList of child objects. Here is the mapping for the one to many relationship:

<bag name="Tiers" cascade="all">  <key column="mismatch_id_no" />  <one‐to‐many class="TGR_BL.PromoTier,TGR_BL"/></bag>

If I try to remove all objects from the collection using clear(), then call SaveOrUpdate(), I get this exception:

System.Data.SqlClient.SqlException: Cannot insert the value NULL into column

If I try to delete the child objects individually then remove them from the parent, I get an exception:

deleted object would be re‐saved by cascade

This is my first time dealing with deleting child objects in NHibernate. What am I doing wrong?

edit: Just to clarify ­ I'm NOT trying to delete the parent object, just the child objects. I have the relationship set up as a one to many on theparent. Do I also need to create a many­to­one relationship on the child object mapping?

nhibernate

edited Nov 19 '08 at 19:51 asked Nov 19 '08 at 17:33Mark Struzinski12.7k 25 82 113

6 Answers

You are getting the first error because, when you remove the items from the collection,NHibernate's default mode of operation is to simply break the association. In the database,NHibernate tries to set the foreign key column on the child row to null. Since you do not allownulls in that column, SQL Server raises the error. Clearing the collection will not necessarilydelete the child object, but one way to do so is to set cascade=all­delete­orphan. This informsNHibernate that it should delete the newly orphaned rows instead of setting the foreign keycolumn.

You are getting the second error because when you call SaveOrUpdate NHibernate first deletesall of the child objects. Then, because neither relationship is marked as inverse, NHibernate alsotries to set the foreign key column in your child table to null. Since the rows have already beendeleted, you receive the second error. You need to set inverse=true on one side of yourrelationship to fix this. This is usually done on the one (primary key or parent) side. If you do notdo this, NHibernate will make the appropriate updates for each side of the relationship.Unfortunately, running two updates is not the appropriate thing to do.

You should always mark one side of your relationships as the inverse side. Depending on howyou code, you may or may not need to use cascading. If you want to take advantage of one shotdeletes as you are trying to do using Clear(), you need to define your cascade.

edited Jan 2 '09 at 16:23 answered Nov 19 '08 at 18:21Chuck6,634 2 16 18

   

 –    

Just to clarify ­ I've only got the relationship defined on the Parent object right now. I've tried to set thecascade on that object to "all" and "all­delete­orphan" with the same results both times. You mean I need todefine a many­to­one relationship on the child object as well? Mark Struzinski Nov 19 '08 at 18:28

     –    And in this case does inverse="true" belong on the parent or child object? Mark Struzinski Nov 19 '08at 18:29

2    –    it belong to the class that does not hold the foreign key... usually the parent. pmlarocque Dec 1 '08 at18:33

    Thanks for this explanation, again an inverse issue caught me out, and seeing it explained like this really

Page 2: NHIbernate_StackOverflow

06/04/2015 How to delete child object in NHibernate? ­ Stack Overflow

http://stackoverflow.com/questions/302720/how­to­delete­child­object­in­nhibernate 2/3

 –    helped. Mark Dickinson Jul 17 '09 at 13:48

1    –    Thanks for the quality explanation lomaxx Oct 26 '09 at 1:33

Acording to Chuck's answer, I've resolved my problem by adding Inverse = true in parentside mapping:

Message has many MessageSentTo:

[HasMany(typeof(MessageSentTo), Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Inverse = true)]public IList<MessageSentTo> MessageSendTos{    get { return m_MessageSendTo; }    set { m_MessageSendTo = value; }}

I am using Castle ActiveRecord. Thank you Chuck.

edited Jul 23 '10 at 9:59 answered Jul 23 '10 at 9:48hanuman0503138 5 16

In our example we have categories with many products where a product is not nullable.

You can work around the problem by deleting the product and removing it from the parent'scollection before the flush but we're still looking for a better solution to this.

product = pRepo.GetByID(newProduct.ProductID);product.Category.Products.Remove(product);pRepo.Delete(product);

Hope it helps anyway

answered May 27 '10 at 16:31Liath4,456 6 16 44

     –    This requires another repository though. UpTheCreek Oct 18 '10 at 13:25

Change cascade attribute value from "all" to "all­delete­orphan".

answered Nov 19 '08 at 17:49Thomas Tekavec41 3

     –    Tried this. I'm still getting the same exception. Mark Struzinski Nov 19 '08 at 17:52

15   –    

all­delete­orphan deletes the children when you delete the parent. it doesn't have anything to do withdeleting the children like this guy is asking about. Kyle West Nov 19 '08 at 17:56

Try using merge() instead of saveOrUpdate(). Also, make sure your cascade is set to all­delete­orphan and that your parent­child relationship is invertible (inverse=true on the parent and then afield in the child that is the parent­id with not­null=true).

answered Nov 19 '08 at 17:58Elie7,962 12 50 97

set Not­Null = true in your mapping on the column causing the issue. I'm not sure of the exactsyntax though (sorry).

answered Nov 19 '08 at 17:43Kyle West4,495 5 44 80

Page 3: NHIbernate_StackOverflow

06/04/2015 How to delete child object in NHibernate? ­ Stack Overflow

http://stackoverflow.com/questions/302720/how­to­delete­child­object­in­nhibernate 3/3

   

 –    

Ok, I set the column to not­null="true" on the child object's mapping. So, I call the clear() method on theIList of child objects, then try a SaveOrUpdate(). I'm still getting the "Cannot insert the value NULL intocolumn" error. Am I doing something else wrong? Mark Struzinski Nov 19 '08 at 17:50

     –  

which column is the error being thrown on? how exactly are you deleting the children in your model?Kyle West Nov 19 '08 at 17:58

    –    

I'm calling the clear() method on the Ilist child object in my parent object. Then I'm calling SaveOrUpdate()on the parent. Mark Struzinski Nov 19 '08 at 18:01