Wt::Dbo
Added by Mark Travis over 1 year ago
I have a database entity relationship of one to many AND one to one for a parent->child relationship.
A parent can have several children. But there is only one favorite child. There is one parent to many children, but there is one child to parent favorite.
The parent contains a weak_ptr to the favorite child. It also contains a collection ptr to all children.
The child contains a strong ptr to the parent, as well as a Wt::Dbo::OnDeleteCascade, because if the parent is kicked out, the children need to be kicked out as well.
This isn't working well.
If a parent decides they like another child better, I try to update the parent to set the weak_ptr to the new child. I'm getting a stale object error . If I look at the SQL statements, it appears that the parent is deleted from the database, the parent is modified, then the parent is re-added to the database to reflect the changes. Am I interpreting this correctly?
Is this what https://redmine.webtoolkit.eu/issues/2053 references? If I change the child to OnDeleteSetNull, will this work?
Replies (7)
RE: Wt::Dbo - Added by Plug Gulp over 1 year ago
Just curious, why are you using weak_ptr for favourite child?
RE: Wt::Dbo - Added by Plug Gulp over 1 year ago
Plug Gulp wrote in RE: Wt::Dbo :
Just curious, why are you using weak_ptr for favourite child?
Sorry, my bad; it is a 1-1 relation, so you are right.
RE: Wt::Dbo - Added by Roel Standaert over 1 year ago
I'm not entirely sure what you're doing. If you can cook up a code sample, that would be helpful.
RE: Wt::Dbo - Added by Mark Travis over 1 year ago
Ok, I’ll put something together in a few weeks.
My intent was to keep the pointer handy at the parent level to the child, since I’m already passing the parent object between modules and didn’t want to access the children unless I had a reason to go to that level.
But for now, it was easier to just let the favorite child carry the flag and query the children for the flag carrier when the parent was introduced. Bigger fish to fry in the meantime. Like getting my app out to paying customers. :) But it would be nice to understand Dbo better, so I’ll come back to this shortly.
RE: Wt::Dbo - Added by Christian Meyer over 1 year ago
Hi
The Question should be if the Child needs to know if it is the favorite one...
If not, an alternative would be to use a ptr for the favorite child as a field on the parent.
If you are passing the parents anyway and want the info there, this should be what you want to do?
Good luck with the paying customers
RE: Wt::Dbo - Added by Mark Travis over 1 year ago
Exactly! The child doesn't need to know.
But the 1:1 relationship exists, so a weak_ptr is needed at the parent. This works fine until you need to delete a parent, then the OnDeleteCascade bites you because of the existing 1:M relationship that exists between one parent and ALL of the children.
I think what's happening "behind the scenes" is if I change that weak_ptr from one child to another, instead of updating the parent record, Wt deletes the parent record with the former-favorite-child weak_ptr and then re-adds the parent record with the new favorite-child weak_ptr. That process then triggers the 1:M OnCascadeDelete, where it tries to delete all children, then the "stale object error" appears.
At least, that is my hypothesis at this time. I'll come back to it when I get some time to study it more in-depth. Maybe it's a simple fix, maybe not.
RE: Wt::Dbo - Added by Christian Meyer over 1 year ago
Then you shouldn't need a 1:1 Relationship if I understand Dbo correctly.
You could use Wt::Dbo::field(a, childPtr, "favourite"); on the parent with childPtr of type ptr not weak_ptr
This does not interfere with the 1:M relationship and the DeleteCascade.
Because for Updates you only touch the parent then =)