How is a delete of an aggregate root handled in DDD?
Asked Answered
T

2

13

I have two an aggregate root referencing another aggregate root (first references the second via the identity of the second aggregate root).

A command from my application layer (via MVC asp.net) now deletes my second aggregate root.

At the point of deleting the root, do I send a Domain Event telling the first aggregate root to "NULL" the reference to the second aggregate which now does not exist?

JD

Trelliswork answered 20/12, 2011 at 16:50 Comment(0)
R
12

You're going about it the wrong way. Step back from the technical issue you are facing. First of all I doubt there is such a thing as "Delete" in your ubiquitous language. Most likely people will call it "archive", "taking out of order", "remove", "out of stock", ... some term that denotes that a particular aggregate is at the end of its life-cycle. When domain experts speak of such things, this should be a trigger for you to ask them a question along the line of : "Well if you discontinue a Product, how will that affect a Promotion for that particular Product?". To correlate back to your issue: Promotion being the aggregate that holds a reference to the Product aggregate. So it very much becomes a business issue rather than a technical one. Most of the time business people already have a process in place that prevents this technical issue from happening in the first place (e.g. you can't discontinue a Product that's being used in a Promotion). I hope it's clear by now that giving you a generic answer is not an option.

Reganregard answered 22/12, 2011 at 12:59 Comment(6)
Thank you for your reply. Yes, I have been looking at it too much from the technical point of view. Okay, in this case we have a storage of video files and where a file can be deleted. A user actually deletes a video file which is now referenced by my second aggregate. Talking to the business analyst, his reply is that I should log it in an event file and remove it from the recorder service. When the recorder service runs, it will not fail and at that time it will be dealt with. So in my case I do have to "NULL" it in the second aggregate. What is the correct way to do this?Trelliswork
So basically users can delete videos which means that they are physically deleted from our application. There is no other way I can put it which will define "end of its life cycle". I did ask if we could prevent the video from being deleted if it is used elsewhere (in another aggregate) but the reply was it was not important and we should simply allow the deletion (i.e. we have 1000s of videos and trying to work out who is using them (i.e. the aggregate) is too much work and not that important to the user).Trelliswork
A video file seems hardly an aggregate then. It's a physical resource (at least compared to the rest of the model). How is a video file used in another aggregate? As a reference to the path of the video file? Or do you load it up in the aggregate that references it, to perform video-editing during the command execution? If you could somehow query the affected aggregates in response to the video file deletion, you could send them a message stating the video is no longer available. BTW, are you using event sourcing or Udi Dahan's variety of domain events? Event storage or a regular ORM?Reganregard
The video file as I have modelled it has lots of meta data. Maybe I should have said videoContainer instead. It will have a reference to the video file, so yes it is loaded up in the aggregate VideoContainer. I am still getting my head around DDD (bounded context etc) and have only just learnt about Event sourcing which I the way I will probably go.Trelliswork
I would +1 this answer for encouring the OP to rephrase the problem using the ubiquitous language, but the fact is, you haven't actually answered the question. It doesn't matter if you call the removal of the AR from the current state "deleting", "unpublishing", "archiving", etc. The question is that in transitioning from one state - in which the AR exists and is referenced by other entities - to the next state - where the AR no longer exists - how do the entities referencing the original AR get updated? The term "referential integrity" isn't just confined to DBAs use of foreign keys.Crabber
I think the idea of referential integrity is a red herring in this case. If there's a desire for strong consistency between multiple entities, then reconsider the aggregate boundaries. As for making other entities aware of referenced entity/aggregate no longer being there, I think my answer challenged exactly that. Other than that, trying to bring the question back to "entity and aggregate"-speak is exactly why we run into problems - in general, that is. The answer is (most often) to be found in the sphere of activity the software is being built for.Reganregard
U
3

I think the question was not actually answered by another responder that has been here for a while. I also think that those who come here deserve an answer. I will answer the question (see #2), but let me first clarify something.

#1 Why Not Delete?

So, first, I agree with another answer and will say that in domain terms, there is no such thing as deletion typically. I like the angle from which this article by Udi Dahan explains the point.

My explanation for being against the deletion is a bit old-style, simpler (yes, even simpler), and hopefully easier to understand. Imagine a world without (or before) computers. People did everything on paper. Imagine (I know it might be awkward) that you are dealing with a book instead of the video. A book that contains the same info as the video you are deleting. You can't delete the book, but you can "burn" it or "trash" it. It actually continues living but changes its form of existence. Similarly, your video moves from its current state to the next state, or maybe it even transforms and gives birth to the object that is its next state. Anyway, the point is, you are changing the state and not deleting it. So, it would be best if you modeled it as a state change. That was the point, although I know it could have been unclear.

#2 How to Update Other Aggregates?

Very simple, the original aggregate (the one that changes state, see above) dispatches an event that describes what happened to it. You subscribe to that event, and the event handler updates other impacted aggregates. I think this was the answer you were looking for without all the "can't delete" conversations. Sorry that I added that part again, but I wanted to clarify both points for readers.

To expand the book's example: when you trash the book, you need to update the book directory (or index paper that shows where each book is in the library), not to mention the trashed book anymore. So without computers, the one who trashed the old book would tell the other guy responsible for the directory to scratch the book from the list (read as "when the book is trashed, the directory must remove it from the list"). That is what the event accomplishes but in digital terms.

Unbacked answered 18/3, 2021 at 13:40 Comment(4)
"the original aggregate ...dispatches an event" how would it do that if it is just deleted from the repository? I get what you mean, but i don't see how it would actually happen.Othelia
Perhaps I was not clear. Nothing gets actually deleted from the repository. When you want to delete something, you change its state, that's all. So, you may have book.MarkAsObsolete() operation, and then repository.Update(book). MarkAsObsolete dispatches the event. You do not delete the book, you mark it as obsolete (i.e., change its state). Does this clarify my point?Unbacked
Yes, but at the same time no :D Lets assume deletion is strictly necessary (think GDPR or just a very rapid accumulation of data otherwise). How would you handle that?Othelia
Okay, so, if you really need to delete the data, that would only be possible after the entire system has digested the events properly (i.e., everything became consistent after the book became obsolete). So, perhaps you would do that in a cleanup job or somewhere: you would identify all obsolete books that were processed till the consistency point (i.e., events were processed and it's safe to cleanup the data), and then you would delete the data that does not affect the system's consistency. That is how I would do it. The whole point is in consistency.Unbacked

© 2022 - 2024 — McMap. All rights reserved.