I have a parent-child relationship where I have multiple child objects. The first child object saves successfully, but the second doesn't, and the database transaction performs a rollsback. The parent object and the second child are still marked as new (isNew = true), but the first child is not (isNew = false).
When the data is updated and resubmited, the framework now tries to update the first child instead of inserting it, which throws an error (because it was rolled back last time).
What is the best way to rollback all of the child objects to being new, so that when I save next time, it inserts instead of updates?
We are using framework 2.1.4.
If you have everything wrapped transactionally, your Save() will fail and your database will obviously be where you want it to be.
I'm not sure when this was introduced but it's in the latest version of the framework (recently defaulted to do this, before you could enable this behavior) but you can send a cloned version of the object in an override for Save, so that when your update fails, you fall back on the original object - if the update succeeds, the result from the save is the one you use.
That's really the easiest manner to do it. There is an overhead to cloning an object, but it'll give you clean behavior in this area of concern.
This really should not be happening. Data portal should
throw an exception in Save() of parent object, and you should not be re-binding
to broken objects that come back from data portal. Could you show what
your code looks like that calls Save()?
Sergey Barskiy
Principal Consultant
office: 678.405.0687 |
mobile: 404.388.1899
Magenic ®
Microsoft Worldwide Partner of the Year | Custom
Development Solutions, Technical Innovation
From: Gregd
[mailto:cslanet@lhotka.net]
Sent: Sunday, August 10, 2008 9:49 PM
To: Sergey Barskiy
Subject: [CSLA .NET] Mark child objects as new when database transaction
fails
I have a parent-child relationship where I
have multiple child objects. The first child object saves successfully, but the
second doesn't, and the database transaction performs a rollsback. The parent
object and the second child are still marked as new (isNew = true), but the
first child is not (isNew = false).
When the data is updated and resubmited, the
framework now tries to update the first child instead of inserting it, which
throws an error (because it was rolled back last time).
What is the best way to rollback all of
the child objects to being new, so that when I save next time, it inserts
instead of updates?
We are using framework 2.1.4.
Assuming you are doing the entire save operation in a transaction (e.g. all children are being saved in the same transaction), the easiest way to avoid this problem is to save a clone of the object rather the object itself. If the Save() fails, then the original object is unmodified, reflecting the state of the database after the Rollback().
In CSLA 3.0 and later, there are provisions for having this happen automatically (e.g. an AutoCloneOnUpdate setting). However, you have to remember that you need to replace your original reference to the object with the one returned from the Save() operation.
Thanks everyone. We found the problem was that we were saving the object to viewstate, and that was why it didn't rollback.
We have created a new AutoCloneOnUpdate property and updated the functions so that it now works like CSLA 3.0.
Thanks
Copyright (c) Marimer LLC