Question

I'm getting the classic error:

'deleted object would be re-saved by cascade 
(remove deleted object from associations)[DrillingContracts.Domain.TrackedField#3216' 

But with an added twist, The error is originating entirely because I'm deleting one entity and adding a NEW one.

I empty all the pre-existing children with this method

 public void RemoveChildren(TrackedNode parentNode)
        {
            foreach (TrackedField trackedField in parentNode.ChildNodes)
            {
                _trackedFieldRepository.Delete(trackedField);
                parentNode.RemoveChildNode(trackedField);
            }
        }

Then add the new ones immediately next

public virtual void AddTrackedChildFieldsToTrackedCell(
        params TrackedField[] nodes)
    {
        foreach (var field in nodes)
        {
            if (IsPath(field.Name))
            {
                throw new InvalidTrackedFieldNameException(
                    "The value " + field.Name + " is not a valid tracked field name.");
            }
                field.Supplement = this;
                _trackedFields.Add(field);
        }
    }

For those of you who want to know what is happening in the repository the best answer I have is magic. 10,000% magic. The original developer used NCommon. Both of these methods are called from a method wrapped in the NCommon.UnitOfWork attribute.

It should be noted that each method performs as expected on its own. (IE, no fields to delete the add works, and likewise, no fields to add the delete works.)

EDIT

[HttpPost]
[UnitOfWork(Scope = FilterScope.Result)]
public ActionResult SaveEditMode(long id, AddTrackedRowViewModel model, string editMode, List<string> elementNames, string provisionData)
        {
            var supplement = _supplementCoordinator.GetSupplement(id);
            var table = supplement.TrackedTables.First(x => x.Name == model.Name);

                var valueAttributes = JsonSerializer.DeserializeFromString<List<ValueAttributeViewModel>>(provisionData);
                foreach (var prop in valueAttributes)
                {
                    supplement.Set(prop.Attribute, prop.Value, false);
                }

                var cell = table.TrackedRows.First(x => x.Ordinal == model.Ordinal).TrackedCells.First(x => x.Name == "Detail");
                _supplementCoordinator.RemoveChildren(cell);

                if (elementNames != null)
                {
                    var childNodes = elementNames.Select((t, i) => new TrackedField(cell, t, i)).ToList();
                    supplement.AddTrackedChildFieldsToTrackedCell(childNodes.ToArray());
                }


                return SwitchEditMode(model, editMode, table);
        }

Answer

public void AddChildren(Supplement supplement, TrackedNode parentNode, params TrackedField[] nodes)
    {
        foreach (TrackedField trackedField in nodes)
        {
            parentNode.AddChildNode(trackedField);

        }
        supplement.AddTrackedChildFieldsToTrackedCell();
    }

I wasn't getting them added as new entitles to the parent node, just the associated supplement.

Was it helpful?

Solution

Just for completeness. The message 'deleted object would be re-saved..' was caused by the explicit call session.Delete(instance).

In this case, we only need to 1) remove such item from the old parent collection and 2) append it to new parent. The cascade mapping and session.Flush() will properly upate DB.

Final note: such a "movement" must be done inside one session/transaction, to avoid other issues (e.g 'Row was updated or deleted by another transaction...').

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top