markhildreth

markhildreth

Domain Modeling Made Functional questions

@swlaschin

Written in the persistence chapter under the section “Writing to a relational database”, that “we convert our domain object to a DTO and then execute an insert or update command.” I have a few questions on this.

1.) This doesn’t really seem to handle deletes. How would you recommend handle a command which deletes the root aggregate (and presumably all of its “children”)? Would the DTO just end up being a “null” which the persistence mechanism takes to mean “delete it all”?

2.) More troublesome, how would the aggregate root not be deleted but a child be deleted (e.g., removing an order line from an order).

Would we need to “mark” the line as deleted in our aggregate in order to know during persistence that it should be deleted? That seems like it would complicate the model for reasons of persistence.

Or perhaps our persistence logic deletes all order lines in the DB with IDs that are not in the order line DTO array?

Or maybe we retrieve the current state of the database as a DTO, do a diff with the DTO created as a result of our command

3.) In both of these questions (and specifically the second), there is the problem of concurrent transactions affecting the same aggregate. Are we essentially forced to use serializable transactions or record locking if we want to ensure that two transactions are not stepping on each others toes? Or is there another strategy here (besides strategies like event sourcing).

Thanks

First Post!

swlaschin

swlaschin

Author of Domain Modeling Made Functional

Thanks for the questions!

  1. Deletes generally just need an entity id, not a DTO. For a compound object like an Order, if the database supports it, I would set up a cascade delete. Otherwise you could query for the subobjects and explicitly delete them. In both cases I would hide all this logic inside the infrastructure component (API call wrapper) rather than exposing it to the domain logic.

  2. Removing a line from an Order would be treated as an Update from the domain’s point of view. It depends whether you want to expose the logic to the domain layer. If you want to hide it, I would pass in the modified DTO without the line and then, inside the infrastructure component (the API call wrapper), figure out which lines are missing (delete), which lines are added (insert), and which lines are changed (update). This approach means that ANY updates to the aggregate root (additions, subtractions, etc) are handled the same way, using the same infrastructure method. More complicated, but it keeps the domain logic simple.

  3. The problem of concurrent changes to the same aggregate is not specific to any particular design method and there are standard approaches you can use. If you have independent processes updating the database, you can use pessimistic concurrency (locks, transactions) or optimistic concurrency (versioning, timestamps). If everything is handled by one server (e.g. when doing microservices), then you can represent each aggregate root with an agent, and changes to the object are queued up and serialized that way. Or, yes, you can use event sourcing :slight_smile:

Hope this helps!

Where Next?

Popular Pragmatic Bookshelf topics Top

ianwillie
Hello Brian, I have some problems with running the code in your book. I like the style of the book very much and I have learnt a lot as...
New
jesse050717
Title: Web Development with Clojure, Third Edition, pg 116 Hi - I just started chapter 5 and I am stuck on page 116 while trying to star...
New
jskubick
I’m running Android Studio “Arctic Fox” 2020.3.1 Patch 2, and I’m embarrassed to admit that I only made it to page 8 before running into ...
New
nicoatridge
Hi, I have just acquired Michael Fazio’s “Kotlin and Android Development” to learn about game programming for Android. I have a game in p...
New
brunogirin
When I run the coverage example to report on missing lines, I get: pytest --cov=cards --report=term-missing ch7 ERROR: usage: pytest [op...
New
kolossal
Hi, I need some help, I’m new to rust and was learning through your book. but I got stuck at the last stage of distribution. Whenever I t...
New
Henrai
Hi, I’m working on the Chapter 8 of the book. After I add add the point_offset, I’m still able to see acne: In the image above, I re...
New
Keton
When running the program in chapter 8, “Implementing Combat”, the printout Health before attack was never printed so I assumed something ...
New
dtonhofer
@parrt In the context of Chapter 4.3, the grammar Java.g4, meant to parse Java 6 compilation units, no longer passes ANTLR (currently 4....
New
redconfetti
Docker-Machine became part of the Docker Toolbox, which was deprecated in 2020, long after Docker Desktop supported Docker Engine nativel...
New

Other popular topics Top

ohm
Which, if any, games do you play? On what platform? I just bought (and completed) Minecraft Dungeons for my Nintendo Switch. Other than ...
New
DevotionGeo
I know that these benchmarks might not be the exact picture of real-world scenario, but still I expect a Rust web framework performing a ...
New
AstonJ
Curious to know which languages and frameworks you’re all thinking about learning next :upside_down_face: Perhaps if there’s enough peop...
New
AstonJ
If you get Can't find emacs in your PATH when trying to install Doom Emacs on your Mac you… just… need to install Emacs first! :lol: bre...
New
AstonJ
Was just curious to see if any were around, found this one: I got 51/100: Not sure if it was meant to buy I am sure at times the b...
New
hilfordjames
There appears to have been an update that has changed the terminology for what has previously been known as the Taskbar Overflow - this h...
New
PragmaticBookshelf
Develop, deploy, and debug BEAM applications using BEAMOps: a new paradigm that focuses on scalability, fault tolerance, and owning each ...
New
AstonJ
If you’re getting errors like this: psql: error: connection to server on socket “/tmp/.s.PGSQL.5432” failed: No such file or directory ...
New
AnfaengerAlex
Hello, I’m a beginner in Android development and I’m facing an issue with my project setup. In my build.gradle.kts file, I have the foll...
New
PragmaticBookshelf
A concise guide to MySQL 9 database administration, covering fundamental concepts, techniques, and best practices. Neil Smyth MySQL...
New

Sub Categories: