fluent nhibernate one to many parent delete - fluent-nhibernate

We have 2 classes, Parent and Child
The parent has no reference to the child, the child has the following defined in its fluent mapping:
References(x => x.Parent, "Parent_id").Not.Nullable();
When the parent record is deleted, the following error is generated:
The DELETE statement conflicted with the REFERENCE constraint "FKFF68C21EE06905B9". The conflict occurred in database "DatabaseName", table "dbo.tblChild", column 'Parent_id'.
The statement has been terminated.
What would be the correct mapping to enable the deletion of the parent, given that the parent model has no property collection of type child?

You cannot delete parent records, that are referenced by child records because of the foreign key constraint. If you do not want to map the children as a collection reference, you will have to delete the reference to the parent record in all child record before deleting the parent record. You can do so by setting the reference to the parent to null (removing your not null constraint) or by deleting the child record.
All other solutions include an inverse child collection in your parent record with a cascade mapping.

Related

Child table doesn't receive data from parent in phpMyAdmin

I'm fairly new to phpMyAdmin, and I've come across a problem...
I have two tables in my database, Parent and Child. Both have an ID and username field, and I've set up the foreign key in working order (e.g. if I change the Parent.id, the Child.id get changed aswell.
However, I wish the Child table would automatically create a new record for each new entry made in the parent. So if I create a new Parent.id, Child should display the newly created Parent.id.
Example when I insert into Parent a new username, it'll get ID of 1 and username 'Daniel'.
I want child to have these values aswell in Child.id and Child.username respectively, so Child gets filled with 1, 'Daniel' aswell.
As for now, Child remains empty with every record I insert into Parent.
Is there a 1:1 relationship between parent and child? (Typically we use the terms 'parent' and 'child' to refer to two sides of a 1:M relationship, so that is a little confusing.)
Have you considered a trigger? The trigger would update the child the way you want, each time you do something to the parent. Here is the description of how to add a trigger to an insert command in MySQL.

NHibernate One-to-Many - why is it updating child with null foreign key?

I am troubleshooting code that is attempting to update a disconnected entity that has uninitialized references to child entities. The intent is to update only the properties on Parent without loading children.
HasMany(x => x.ChildEntities)
.KeyColumn("ChildEntityId")
.Table("ChildEntity")
.Not.LazyLoad()
.Inverse()
.Cascade.All().AsBag();
When Session.Update(parent) is called, two update statements are executed. The first updates the parent object as expected.
update Parent set ... where ParentId = 12345
The second update confuses me...
update ChildEntity set ParentId = null where ParentId = 12345
Why is NHibernate issuing that second SQL statement? I realize that ChildEntities is uninitialized and that NHibernate is probably trying to enforce the state of Parent but I can't seem to tweak the mapping to not make this second update. I've tried Merge, lazy loading, various cascade options, etc. without success. The only connected entity in the session when it tries to commit is Parent.
Note that I typically approach this by retrieving the entity with lazy loading enabled and then mapping from the disconnected object (DTO or entity) to the connected entity before letting NHibernate persist to the database. I want to understand why the above isn't working before I suggest an alternative approach.
This was annoying.
A quick search through the NHibernate source for "could not delete collection" showed up in a block that could only execute if !isInverse (AbstractCollectionPersister.cs). That drew my attention because the mapping code was explicitly setting Inverse on that collection.
If Inverse is false and the collection is empty, NH executes an update on the child table setting the foreign key to null where the foreign key equals the parent id.
Fluent is configured to auto-map all entities in a given namespace. The assumption was that anything with a manual mapping would be ignored by auto mapping. A quick check of the hbm.xml files produced by Fluent confirmed that Inverse was not being set. I added Parent to the list of entities that were explicitly excluded from Auto Mapping and everything started working.
.IgnoreBase<Parent>()

persiste the deletion operation from a collection in NHibernate

When i delete some object (or remove it) from a collection (such as list) and call SaveOrUpdate from the parent of this collection the row of the child isn't removed but updated by setting the foreign key value to NULL.
How can i force it to be deleted (the child row).
You need to mark the collection as the inverse side of the relationship and set the cascade setting to all-delete-orphan. NHibernate is attempting to update the foreign key to null because you have created an orphan by removing it from the collection but haven't instructed it to delete orphans.

how to remove one-to-many child from parent given the child id in HQL

I've got
class Parent
{
IList<Child> Children;
}
class Child
{
}
When deleting a Child I need to remove all references to it from any Parents that reference it.
How can I do this in NHibernate?
There is no Parent FK on Child, the relationship is stored in a 3rd "link" table
Thanks
This is not a parent-child relation. Children have only one parent (the belong to the parent). This is a many-to-many relation between independent entities. This is a important difference.
You can't actually remove the "children" from the "parent" directly in HQL the way it is designed now. This are your options:
load the "parents" into memory and remove the "child" from the list.
Add a reference from the "child" back to the "parents". Make the other relation inverse. It should actually automatically remove the item in the link table when you remove a "child", because the link would belong to the "child" then.
Delete the link using native SQL. This is not nice, but also not too bad because it is trivial standard sql.
To make this happen, there needs to be a relationship of some sort, starting from the Child Entity.
Then you can simply use cascade-delete to its 3d (I'm guessing this is a many-to-many) table.

Why am I getting "multiple cascade paths" with this table relationship?

I have the following table relationship in my database:
Parent
/ \
Child1 Child2
\ /
GrandChild
I am trying to create the FK relationships so that the deletion of the Parent table cascades to both child and the grandchild table. For any one particular granchild, it will either be parented to one or the other child tables, but never both at the same time.
When I'm trying to add ON DELETE CASCADE to the FK relationships, everything is fine adding them to one "side" of the two children (Parent-Child1-GrandChild is fine for Cascade Delete). However, as soon as I add the Cascade Delete on the Child2 "side" of the relationship SQL tells me that the FK would cause multiple cascade paths. I was under the impression that multiple cascade paths only apply when more than one FK indicates the SAME table. Why would I be getting the multiple cascade paths error in this case?
PS The table relationships at this point would be very difficult to change so simply telling me to change my table structure is not going to be helpful, thanks.
The message means that if you delete a Parent record, there are two paths that lead to all deletable GrandChild records.
Fix: Remove the ON DELETE CASCADE options in the FKs, and create INSTEAD OF DELETE triggers for the ChildX tables, deleting all grandchild records, and then the childX records themselves.