3

I have one-to-many relationship between category and product. They are linked via categoryId field in the mapping. The category record will never get deleted, but the products children should get deleted. I send different payloads (based on logic) to my service via json. My product array I send one time is like this:

"products": [{Id=0, Name="p1"}]

it adds it fine and then 2nd time adds it fine:

"products": [{Id=111, Name="p1"},{Id=0, Name="p2"}]

Here the DB properly shows:

|-------|------|------------|
|  Id   | Name | CategoryId |
|-------|------|------------|
|  111  | p1   | 123        |
|  222  | p2   | 123        |

But if I am sending empty array of products, I'm expecting that both product records in DB will be deleted:

"products": []

but they don't.

Here is my NHibernate Fluent setup:

public CategoryMap()
{
    Table("Category");
    LazyLoad();

    Id(q => q.Id).GeneratedBy.Identity().Column("Id");

    HasMany(q => q.Products)
        .KeyColumn("CategoryId")
        .Cascade
        .AllDeleteOrphan()
        .Inverse();
}

and in my child:

public ProductMap()
{
    Table("Product");
    LazyLoad();

    Id(x => x.Id).Column("Id").GeneratedBy.Identity();

    Map(x => x.Name).Column("Name");

    References(x => x.Category).Column("CategoryId").Not.Nullable();
}

The result here:

|-------|------|------------|
|  Id   | Name | CategoryId |
|-------|------|------------|
|  111  | p1   | 123        |
|  222  | p2   | 123        |

I have also tried making my QuestionId nullable in DB and in my child configuration:

References(x => x.Category).Column("CategoryId").Nullable();

The result here:

|-------|------|------------|
|  Id   | Name | CategoryId |
|-------|------|------------|
|  111  | p1   | NULL       |
|  222  | p2   | NULL       |

I want the children to be completely wiped out. What am I doing wrong? Please note that I am want to keep the parent record.

user1019042
  • 2,428
  • 9
  • 43
  • 85
  • 1
    Can you try this? https://stackoverflow.com/a/11981259/194717 – Tony Jan 22 '18 at 19:15
  • thx. it didn't work. I tried it with both: .Nullable and .Not.Nullable the records keep showing up. I think the SaveUpdate() is necessary to at least make the categoryId null – user1019042 Jan 22 '18 at 19:35
  • Are you just setting the Products collection to a new instance? I believe you should .Remove() the items or .Clear() the collection instead for cascade to work properly. – Fredy Treboux Jan 24 '18 at 19:30
  • I want the removal to be taken care of by NHibernate based on the payload the service receives. If the payload has a new item with id = 0, then it saves and when I send the same object with populated id then it is update. If I don't send the object, it removes and so on – user1019042 Jan 25 '18 at 14:02
  • How are you calling the NHibernate API to perform the deletion? Can you post the code that executes the delete statement to the database? – Ibn Masood Jan 26 '18 at 19:42
  • @arbabk My understanding of how NHibernate works that if I have products as children of category and I have in DB this product: "products": [{Id=111, Name="p1"}] and I send: "products": [{Id=0, Name="p2"}] it will delete the one with id "111" and add the new one with id "0", is this understanding correct? I got it as far that sets the foreign key (CategoryId) to Null. I want them to be completely deleted, not remain in DB with the Null foreign key. – user1019042 Jan 29 '18 at 00:52
  • @user1019042 pretty sure you will need to call `category.Products.Clear()` to reset the collection before adding the new ones. – jenson-button-event Jan 30 '18 at 11:02
  • @jenson-button-event thx. I don't have problem adding them to the collection... The real problem is how to delete the children from DB instead of keeping them there with CategoryId being Null. – user1019042 Jan 30 '18 at 13:58
  • @user1019042 yes but `Clear` should explicitly do that. simply replacing the array would not. also you should load them before `Clear()` (i notice you have lazy load set). – jenson-button-event Jan 31 '18 at 14:41
  • I don't want the bounty to go down the drain... make ur comment as answer quickly. – user1019042 Jan 31 '18 at 18:37
  • When you state that you send different payloads to your service via JSON, what type of service is this? – Larry Dukek Jan 31 '18 at 19:29

1 Answers1

0

Clear should explicitly do that. Simply replacing the array would not. Also you should load them before Clear (i notice you have lazy load set).

jenson-button-event
  • 18,101
  • 11
  • 89
  • 155